文件操作、网络编程、多线程

文件操作

1、转换File对象
//一个带路径的字符串可以转换为File对象,指向该文件路               
String str = "E:/笔记/第五周/20220920.md";//该字符串为文件路径
//转换File对象
File f = new File(str);//或者 File f = new File("E:/笔记/第五周/20220920.md")
2、判断文件是否存在
2.1、exits方法
File f = new File("E:/笔记/第五周/20220920.md")
boolean exists = f.exists();//true存在 flase不存在
System.out.println("文件是否存在:"+exists);
3、判断是否是文件夹
3.1、isDirectory方法
File f = new File("E:/笔记/第五周/20220920.md")
boolean directory = f.isDirectory();
System.out.println("是否是文件夹"+ directory);
4、判断是否是文件
4.1、isFile方法
File f = new File("E:/笔记/第五周/20220920.md")
boolean file = f.isFile();
System.out.println("是否是文件:"+ file);
5、获取文件名
5.1、getName方法
File f = new File("E:/笔记/第五周/20220920.md")
String fileName = f.getName();
System.out.println("文件名是:"+ fileName);
6、获取文件大小
6.1、length方法
File f = new File("E:/笔记/第五周/20220920.md")
long length = f.length();
System.out.println("文件大小是:"+ length);
7、相关权限
7.1、文件可读read
boolean read = f.canRead();//是否可读
7.2、文件可写write
boolean write = f.canWrite();//是否可写
8、创建一个空文件
8.1、createNewFile方法
boolean r = f.createNewFile();
System.out.println(r);
File z = new File("E:/新笔记");
z.mkdir();//创建一个物理目录
9、删除文件夹(文件)
File z = new File("E:/新笔记");
z.delete();//删除,如果里面有内容,就不能删除
9.1、遍历删除文件夹目录下所有的文件
// 需求:定义方法,把素材3里面所有的目录和文件全部删除 (可使用递归算法,也可以通过框架的方法来实现)
public class Demo7 {
    public static void show(File baseFileDir,int level){
        File[] subFiles = baseFileDir.listFiles();
        for (File subFile:subFiles) {
            if (subFile.isFile()) {//是文件
                subFile.delete();
                System.out.println("删除成功"+ baseFileDir.getName());
            }else {
                for (int i = 0; i < level; i++) {
                    subFile.delete();

                }
                System.out.println(subFile+"删除成功"+ baseFileDir.getName());
                show(subFile,level+1);
            }
        }
    }
    public static void main(String[] args) {
        //获取根目录
        File baseFileDir = new File("src/com/company/Day20/素材");
        show(baseFileDir,1);
    }
}
10、获取下一级文件目录
10.1、遍历文件夹目录
File f = new File("E:/笔记/第五周/20220920.md")
String[] list = f.list();
File[] fi = f.listFiles();
for (String l:list) {
    System.out.println(fi.getClass());
}
public class Demo4 {
    //需求:打印所有目录名称和文件名称
    public static void printFile(String strPath) {
        File dir = new File(strPath);//传参:将路径传给File对象
        File[] files = dir.listFiles(); // 该文件夹目录下所有文件全部放入数组
        if (files != null) {
            for (int i = 0; i < files.length; i++) {//遍历所有文件
                System.out.println("文件名:"+files[i].getName());
                if (files[i].isDirectory()) { // 判断是文件还是文件夹
                    printFile(files[i].getAbsolutePath()); // 获取文件绝对路径
                    System.out.println("文件地址:"+files[i].getAbsolutePath() + "\t文件夹名:"+files[i].getName());
                }
            }
        }
    }
    public static void main(String[] args) {
        printFile("E:/hello/src/com/company/Day20/素材3");
    }
}
11、获取时间
11.1、LocalDate方法
LocalDate localDatebirth = LocalDate.parse(birthday);
11.2、获取当前时间
LocalDate localDate = LocalDate.now();
11.3、获取年、月、日
int birthYear = localDatebirth.getYear();
int birthMonth = localDatebirth.getMonthValue();
int birthDay = localDatebirth.getDayOfMonth()
12、文件、图片、视频、MP3拷贝
12.1、Apache框架
/*
需求1:把小乔这个图片,拷贝到备份目录里面
*/
public class Demo3  implements Serializable{
    public static void main(String[] args){
        File srcFile = new File("E:/hello/src/com/company/Day20/素材2/images/小乔.jpg");
//        File desFile = new File("E:/hello/src/com/company/Day20/素材2/备份");
//        FileUtils.copyFileToDirectory(srcFile,desFile);//拷贝图片
//        System.out.println("拷贝成功");
    }
}
/*
写法一:
需求2:把所有图片全部拷贝在备份目录里面
*/
public class Demo3  implements Serializable{
	public static void main(String[] args){
		       File srcFile = new File("E:/hello/src/com/company/Day20/素材2/images");
        File desFile = new File("E:/hello/src/com/company/Day20/素材2/备份");
        FileUtils.copyDirectory(srcFile,desFile);//copyDirectory拷贝目录下所有的文件
        System.out.println("拷贝成功");
	}
/*
写法二:
需求2:把所有图片全部拷贝在备份目录里面
*/
public class Demo3  implements Serializable{
    public static void main(String[] args){
                try {
            BufferedReader reader = new BufferedReader(new FileReader("E:/hello/src/com/company/Day20/素材2/images"));
            String str = null;
            while ((str = reader.readLine()) != null){

            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
13、文件读取
13.1、读取文件里没有交作业的人员
//写一个查询没有交作业的人员程序
    @Test
    public  void ZuoYe() throws IOException {
        try {
//老师写的
            //1、读取人员名单【因为是文件一个又一个字节组成的,所以用BufferedReader】
            BufferedReader bufferedReader = new BufferedReader(new FileReader("E:/hello/src/com/company/Day20/素材1/人员名单.txt"));
            //存放人员名单
            List<String> personList = new ArrayList<>();
            //一行一行的读
            String tx= null;
            while ((tx = bufferedReader.readLine()) != null){
                personList.add(tx);
            }
            //2、获取文件夹里面的所有文件
            //创建一个File对象得到作品清单物理地址
            File dir = new File("E:/hello/src/com/company/Day20/素材1/作业情况");
            //获取下一级目录,就是已交作业的名单
            String[] list = dir.list();//获取文件,如陆小凤_作业.txt
            System.out.println("已交作业的名单:");
            //获取已提交作业的名单
            for (String s:list) {
                System.out.println(s.substring(0,s.indexOf("_")));//截取文件名,比如陆小凤_作业.txt从第一个字符截取到_之前就结束
            }
            //获取未提交作业的名单
            System.out.println("未交作业清单:");
            List<String> unworkList = new ArrayList<>();
            for (String person:personList) {
                boolean r = true;//未提交作业的是true,提交作业的就是false
                for (String s1 : list) {
                    if (person.equals(s1.substring(0, s1.indexOf("_")))) {
                        r = false;
                        break;
                    }
                }
                if (r) {
                    unworkList.add(person);
                }
            }
                System.out.println(unworkList);
            bufferedReader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

13.2、读取人员名单中的人员,并且拷贝该些人的证件照

//写一个查询没有交作业的人员程序
    @Test
    public  void ZuoYe() throws IOException {
        try {
//老师写的
            //1、读取人员名单【因为是文件一个又一个字节组成的,所以用BufferedReader】
            BufferedReader bufferedReader = new BufferedReader(new FileReader("E:/hello/src/com/company/Day20/素材1/人员名单.txt"));
            //存放人员名单
            List<String> personList = new ArrayList<>();
            //一行一行的读
            String tx= null;
            while ((tx = bufferedReader.readLine()) != null){
                personList.add(tx);
            }
            //2、获取文件夹里面的所有文件
            //创建一个File对象得到作品清单物理地址
            File dir = new File("E:/hello/src/com/company/Day20/素材1/作业情况");
            //获取下一级目录,就是已交作业的名单
            String[] list = dir.list();//获取文件,如陆小凤_作业.txt
            System.out.println("已交作业的名单:");
            //获取已提交作业的名单
            for (String s:list) {
                System.out.println(s.substring(0,s.indexOf("_")));//截取文件名,比如陆小凤_作业.txt从第一个字符截取到_之前就结束
            }
            //获取未提交作业的名单
            System.out.println("未交作业清单:");
            List<String> unworkList = new ArrayList<>();
            for (String person:personList) {
                boolean r = true;//未提交作业的是true,提交作业的就是false
                for (String s1 : list) {
                    if (person.equals(s1.substring(0, s1.indexOf("_")))) {
                        r = false;
                        break;
                    }
                }
                if (r) {
                    unworkList.add(person);
                }
            }
                System.out.println(unworkList);
            bufferedReader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        
//        try {
//            //读取人员名单
//            BufferedReader bufferedReader = new BufferedReader(new FileReader("E:/hello/src/com/company/Day20/素材3/人员名单.txt"));
//            //创建人员集合
//            ArrayList<String>personList = new ArrayList<>();
//            //定义一个字符串,值为null
//            String str = null;
//            //读取出人员名单里的内容
//            while ((str = bufferedReader.readLine()) != null){
//                personList.add(str);
//            }
//            System.out.println(personList);
//            File srcFile = new File("E:/hello/src/com/company/Day20/素材3/images");
//            File desFile = new File("E:/hello/src/com/company/Day20/素材3/备份");
//            ArrayList<String>list =new ArrayList<>();
//            String[] lists = srcFile.list();
//            for (String s:personList) {
//
//                boolean r = false;
//                for (String s1:lists) {  System.out.println(s.substring(0,s.indexOf(".")));
//                    if(personList.contains(s1.substring(0,s.indexOf(".")))){
//                        r = true;
//                        break;
//                    }if(r){
//                        list.add(s);
//
//
//                    }FileUtils.copyDirectory(srcFile,desFile,r);
//                }
//
//
//                System.out.println(list);
//
//
//            }      System.out.println("拷贝成功");
//        }catch (Exception e){
//            e.printStackTrace();
//        }
    }
}
14、常用的FileUtils
cleanDirectory:清空目录,但不删除目录。

contentEquals:比较两个文件的内容是否相同。

copyDirectory:将一个目录内容拷贝到另一个目录。可以通过FileFilter过滤需要拷贝的 文件。

**copyFile**:将一个文件拷贝到一个新的地址。

**copyFileToDirectory**:将一个文件拷贝到某个目录下。

copyInputStreamToFile:将一个输入流中的内容拷贝到某个文件。

deleteDirectory:删除目录。

deleteQuietly:删除文件。

listFiles:列出指定目录下的所有文件。

openInputSteam:打开指定文件的输入流。

readFileToString:将文件内容作为字符串返回。

readLines:将文件内容按行返回到一个字符串数组中。

size:返回文件或目录的大小。

write:将字符串内容直接写到文件中。

writeByteArrayToFile:将字节数组内容写到文件中。

writeLines:将容器中的元素的toString方法返回的内容依次写入文件中。

writeStringToFile:将字符串内容写到文件中。

网络编程

1、网络编程三要素
1.1、IP地址
含义:如何定位到某台服务器
1.2、端口
含义:如何定位到某个程序

注意:端口最好不要用3306(数据库)、8080、8086

1.3、传输协议
1.3.1、TCP/IP

在Java中类名以Socker开头,是长连接,中途不可断开,传输可靠,但是比较消耗资源。

1.3.2、UDP

在Java在类名以Datagram开头,底层都是用的UDP

1.3.3、Http

超文本传输协议,Web架构,是基本TCP协议的应用层传输协议,简单说就是客户端和服务器端之间的一种数据传规则

1.3.4、其他自定义加密协议
2、网络编程核心API
2.1、服务器端(ServerSocket)
2.1.1、常用方法
  • accept方法:等待客服端的连接,同时产生一个Socket对象和客户端建立一个通信管道
  • 语法:Socket s = 对象名.accecp()
  • 特点:该方法会阻塞(解决办法:利用多线程),直到客户端连接成功才执行下一句代码
  • 如果要连接多个客户端,直接有循环就可以了
2.1.2、创建方式
  • 语法:ServerSockt server = new ServerSoket(端口口);//默认的是自己本机地址,如果不想默认,则双引号+IP地址

  • 调用bind方法,绑定IP和端口号(SocketAddress)

    SocketAddress address = new InetSocketAddress("127.0.0.1",8888);//服务器端ServerSocket server = new ServerSocket();
    //把IP和端口与服务器进行绑定
    server.bind(address);
    
2.2、客户端(Socket)
2.2.1、常用方法
  • getInputStream:从管道里面获取一个输入流,里面的数据是服务端发送过来的
  • getOutStream:从管道俩民获取一个输出流,里面的数据是客服端发送过去的
  • close:关闭和服务器端的连接
2.3、IP+端口
2.3.1、InetAddress
2.3.2、Inet4Address
2.3.3、Inet6Address
2.3.4、SocketAddress
3、线程
3.1、程序、进程、线程的理解
3.1.1、程序:就是一个完成的程序系统,如QQ
3.1.2、进程:进来一个程序,让其运行起来
3.1.3、线程:列如一个聊天程序可以给A发消息,也可以给B发消息,也可以接受消息
3.2、线程的作用
作用:可以解决只能处理一件事(实现一个功能),可以同时跑多个程序
3.3、线程的创建(main方法是主线程,JVM创建的)
3.3.1、通过Thread类来创建
/*
main方法里面打印1-100的偶数,新开一个线程打印1-100的奇数
 */
/*
方式一:通过Thread类来创建
 */
class PrintTask implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(i % 2 != 0){
                try {
                  Thread.sleep(100);//延时100毫秒
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}
public class Thread2 {
    public static void main(String[] args) {
        //开一个线程:一个线程也是一个对象Thread
        Thread t = new Thread(new PrintTask(),"子线程");
        t.start();//调start方法的同时,会自动调PrintTask的run方法
        //启动之前要告诉它要完成什么工作
            for (int i = 0; i < 100; i++) {
                //打印1-100偶数
                if(i % 2 == 0){
                    try {
                            Thread.sleep(100);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+":"+i);
                }
            }
    }
}
3.3.2、通过Extend继承创建
/*
main方法里面打印1-100的偶数,新开一个线程打印1-100的奇数
 */
/*
方式二
通过继承创建新的线程
 */
 public class ThreadExtendDemo extends Thread{
 	//继承Thread,调用Thread里面的run方法
    @Override
    public void run(){
        for (int i = 0; i < 100; i++) {
            System.out.println(i);
        }
    }
    public static void main(String[] args) {
        ThreadExtendDemo t = new ThreadExtendDemo();
        t.run();//调run方法
        t.start();//启动线程,自动调run方法
    }
}
3.3.3、通过线程池(ThreadPool)submit创建、
/*
main方法里面打印1-100的偶数,新开一个线程打印1-100的奇数
 */
/*
方式三:通过线程池创建管理线程
*/
public static void main(String[] args) {
       /*
        JUC:代表java.util.concurrent,这个包全部是线程相关的API
         */
        //含义:创建一个按需增长的线程池,说白了就是里面线程很多,只管用就是了
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(new PrintTask());//自动帮我们创建1个线程来执行PrintTask任务
        //在线程池里管理线程的执行任务
        executorService.submit(() ->{
            for (int i = 0; i < 100; i++) {
                if(i % 2 ==0){
                    System.out.println(i);
                }
            }
        });
        executorService.submit(new PrintTask()::run);//把现有的方法,通过引用
        executorService.shutdown();//关闭线程池,必须加上这句代码
    }
}
3.4、线程的生命周期
3.4.1、新建状态

Thread t = new Thread((-> {方法体}));

3.4.2、就绪状态

start()方法:start方法,线程处于就绪状态,但是不会立即调用run方法,执行由CPU决定

3.4.3、运行状态
3.4.4、死亡(中断)状态

interrupt()方法:该方法让线程中断(死亡)

Thread.currentThread().interrupt();
3.4.5、阻塞(休眠)状态

sleep()方法:该方法让线程运行时处于阻塞(休眠)状态,当时间到了,线程则重新处于就绪状态

该方法的父类是native本地方法,是由底层c/c++构成的,不能开源,所以要放在try catch异常里

	Thread thread2 = new Thread(() ->{
    for (char i = 'a'; i <= 'z'; i++) {
        //线程休眠状态
        try {
            Thread.sleep(100);//native:本地方法,不能开源
            System.out.println(Thread.currentThread().getName()+(char)i);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
},"打印的小写字母:");
3.4、线程调度
3.4.1、获取优先级

setPriority方法

thread1.setPriority(Thread.MAX_PRIORITY)

优先级提供了3个数字:1(最低) 5(中等) 10(最高)

3.4.2、休眠

sleep方法

sleep无参:就是直到优先级高的先执行完,再执行低的线程。

sleep有参:就是该线程休眠的时间

3.4.3、join方法

在线程A运行中,让线程B加入,那就调用join方法,之后B线程运行,线程A则阻塞,等到B执行完之后,线程A继续执行

3.5、线程之间的的数据共享

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zv2GIibn-1664280498602)(E:\笔记\第五周\QQ截图20220923163347.png)]

1)main方法在创建一个及以上的线程对象

1)外部类创建一个锁对象

2)在run方法在对其线程可能发生阻塞现象的代码块加锁以及解锁

案例:

public class Demo3 {
/*
共享数据
用锁
 */
    //创建一个锁对象

    public static class PrintTask implements Runnable {
        int i = 1;
        ReentrantLock lock = new ReentrantLock();
        @Override
        public void run() {
        /*
        方式一:
        如果不加锁的话,线程A、B会出现
         */
//
//            while (i<=100){
//                //加锁
//                lock.lock();
//                System.out.println(Thread.currentThread().getName()+i);
//                i++;
//            } lock.unlock();//解锁

            /*
            方式二:
             */
            while (1 <= 100){
                if(i <= 100){//推荐写法  synchronized(this)  或者 synchronized(类名.class)
                    synchronized (PrintTask.class){
                        System.out.println(Thread.currentThread().getName()+i);
                        i++;
                    }
                }
            }
            /*
            方式三:
             */
//            while (i <= 100) {
//                synchronized (PrintTask.class) {
//                    this.notify();//当前线程唤醒已阻塞
//                    synchronized (this) {//Demo7.class,类名.class;
//                        System.out.println(Thread.currentThread().getName() + i);
//                        i++;
//                        try {
//                            this.wait();//当前线程阻塞
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                        // }
//                    }
//                }
//            }
        }
        public static void main(String[] args) {
            PrintTask printTask = new PrintTask();
            Thread t1 = new Thread(printTask, "线程A");
            Thread t2 = new Thread(printTask, "线程B");
            t1.start();
            t2.start();
        }
    }
}
3.6、线程之间的同步
3.6.1、synchronizes关键字加锁和释锁机制

在可能出现线程阻塞出的代码块添加synchronizes关键字进行锁机制

synchronized (PrintTask.class){方法体}//推荐写法:推荐写法  synchronized(this)  或者 synchronized(类名.class)

注意:synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。

3.6.2、同步方法
public synchronized void syn() {
    System.out.println("这是同步方法...");
}
3.6.3、同步代码块

即有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步。

3.7、线程之间的通信
3.7.1、wait

wait方法:当前持有锁的该线程等待,直至该对象的另一个持锁线程调用

3.7.2、notify

notify方法:通知持有该对象锁的所有线程中的的随意一个线程被唤醒

3.7、可重入锁ReentrantLock
ReentrantLock lock = new ReentrantLock();//创建锁对象
4、网络编程相关案例
4.1、客户端发送文字给服务器端
代码:
//线程处理阻塞的问题
//线程:因为第一个客户端发送的数据如果没有被读取到,
// 那么第二个客户端发送的数据也服务器也接受不到,
// 因此把读写数据的代码新开辟一个路径,就是线程的实现
public class Server3 {
    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);
        SocketAddress address = new InetSocketAddress("127.0.0.1",9091);
        ServerSocket server = new ServerSocket();
        server.bind(address);
        System.out.println("服务器已挂起...");


        //---------------*以下代码是接受客户端发生的数据*----------------

        while (true){
            Socket s = server.accept();
            System.out.println("客户端连接成功"+s.toString());
            Thread t = new Thread(()->{
                InputStream in = null;
                try {
                    in = s.getInputStream();
                    byte[] bufs = new byte[1024];
                    int len = -1 ;
                    if((len = in.read(bufs)) != -1) {
                        String msg = new String(bufs, 0, len);
                        System.out.println("收到客户端发的消息:" + msg);
                    }
                    System.out.println("准备给客户端发生数据了");
                    //数据回传给客户端,回答对方
                                        //write方法也会阻塞,如果客户端没有读,那么会阻塞在这里
                    //无论read还是write都会发生阻塞
                    s.getOutputStream().write("收到".getBytes(StandardCharsets.UTF_8));;
                    s.getOutputStream().flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}
public class Cilent3 {
    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);
        Socket s =new Socket("127.0.0.1",9091);
        OutputStream out = s.getOutputStream();
        System.out.println("连接服务器成功...");
        System.out.print("请输入要发送的字母:"); ;
        String msg= input.next();
        out.write(msg.getBytes(StandardCharsets.UTF_8));
        out.flush();
        System.out.println("发生"+msg+"成功");
        //客户端接受服务器端发的数据

        InputStream in = s.getInputStream();
        byte[] bufs = new byte[1024];
        int len = in.read(bufs,0, args.length);
        String m = new String(bufs,0,len);
        System.out.println(m);
        s.close();

    }
}
4.2、服务器端信息回传到客户端
代码:
/*
客服端转发到服务器端
 */
public class Server5 {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(9091);
        System.out.println("等待客户端连接。。。");
        Socket s = server.accept();
        System.out.println("和客户端建立连接了。。。");
        InputStream in = s.getInputStream();
        byte[] bufs  = new byte[1024];
        int len = -1; // 返回读取的字节个数
        String msg = null;
        if( (len = in.read(bufs)) != -1) {
            msg = new String(bufs,0,len); // 字节数组转换未字符串
            System.out.println(msg);
        }
        s.getOutputStream().write(msg.toUpperCase().getBytes(StandardCharsets.UTF_8));
        System.out.println("发送成功!");
        s.getOutputStream().flush();
    }
}
/*
客服端转发到服务器端
 */
public class Cilent5 {
    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);
        Socket s = new Socket("127.0.0.1",9091);
        System.out.println("输入一段字母:");
        String words = input.next();
        s.getOutputStream().write(words.getBytes(StandardCharsets.UTF_8));
        System.out.println("发送成功!");
        s.getOutputStream().flush();
        InputStream in = s.getInputStream();
        byte[] bufs  = new byte[1024];
        int len = -1; // 返回读取的字节个数
        String msg = null;
        if( (len = in.read(bufs)) != -1) {
            msg = new String(bufs,0,len); // 字节数组转换未字符串
            System.out.println(msg);
        }
        s.close();

    }
}
4.3、客户端上传图片到服务器
代码:
/*
客服端转发到服务器端
 */
public class Server5 {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(9091);
        System.out.println("等待客户端连接。。。");
        Socket s = server.accept();
        System.out.println("和客户端建立连接了。。。");
        InputStream in = s.getInputStream();
        byte[] bufs  = new byte[1024];
        int len = -1; // 返回读取的字节个数
        String msg = null;
        if( (len = in.read(bufs)) != -1) {
            msg = new String(bufs,0,len); // 字节数组转换未字符串
            System.out.println(msg);
        }
        s.getOutputStream().write(msg.toUpperCase().getBytes(StandardCharsets.UTF_8));
        System.out.println("发送成功!");
        s.getOutputStream().flush();
    }
}
/*
客服端转发到服务器端
 */
public class Cilent5 {
    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);
        Socket s = new Socket("127.0.0.1",9091);
        System.out.println("输入一段字母:");
        String words = input.next();
        s.getOutputStream().write(words.getBytes(StandardCharsets.UTF_8));
        System.out.println("发送成功!");
        s.getOutputStream().flush();
        InputStream in = s.getInputStream();
        byte[] bufs  = new byte[1024];
        int len = -1; // 返回读取的字节个数
        String msg = null;
        if( (len = in.read(bufs)) != -1) {
            msg = new String(bufs,0,len); // 字节数组转换未字符串
            System.out.println(msg);
        }
        s.close();

    }
}
4.4、客户端上传单文件到服务器
代码:
public class Server4 {
    public static void main(String[] args) throws IOException {
        //简写,不用IP地址,默认本机IP地址
        ServerSocket server = new ServerSocket(8888);
        //等待客户连接进来,通过s和客户端连接
        Socket s = server.accept();
        /*
        核心代码:一边读、一边写
         */
        new Thread(() ->{
            try {
                InputStream in= s.getInputStream();
                File target = new File("人员名单.txt");
                FileOutputStream out = new FileOutputStream(target);
                byte[] bufs = new byte[1024];
                int len = -1;
                while ((len = in.read(bufs)) != -1){
                    String n = new String(bufs,0,len);                                        s.getOutputStream().write(n.getBytes(StandardCharsets.UTF_8));
                    out.write(bufs,0,len);
                }
                out.close();
                System.out.println("保存文件成功!");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }
}
public class Cilent4 {
    public static void main(String[] args) throws IOException {

        System.out.print("文件路径:");
        String path = new Scanner(System.in).next();
        File f = new File(path);
        if(!f.isFile()){
            System.out.println("文件不存在");
            return;
        }
        Socket s = new Socket("127.0.0.1",8888);
        //从客户端的磁盘把文件读取到内存中来
        FileInputStream in = new FileInputStream(f);
        byte[] bufs = new byte[1024];
        int len = -1;
        while ((len = in.read(bufs)) != -1){
            //String n = new String(bufs,0,len);
            //s.getOutputStream().write(n.getBytes(StandardCharsets.UTF_8));
            s.getOutputStream().write(bufs,0,len);
        }
        System.out.println("发生文件成功!");
        in.close();
        s.close();
    }
}
4.5、实现在线聊天
代码:
/*
服务端
 */
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8888);
        System.out.println("服务器已挂起,等待客户端连接...");
        Socket s = server.accept();
        System.out.println("客户端:"+s.toString()+"连接成功!");
        InputStream in = s.getInputStream();
        byte[] bufs = new byte[1024];
        int len = -1;
        String msg = null;
        while ((len = in.read(bufs)) != -1){
            msg = new String(bufs,0, len);
            System.out.println("来自客服端的信息:"+msg);
        }
        s.getOutputStream().write(msg.getBytes(StandardCharsets.UTF_8));
        System.out.println("发送成功");
        in.close();
        System.out.println("服务器已中断...");
    }
}
/*
客户端
 */
public class Cilent {
    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);
        Socket s = new Socket("127.0.0.1",8888);
        System.out.println(s.toString());
        OutputStream out = s.getOutputStream();
        while (true){
            System.out.print("请输入要发送的内容(N退出):");
            String chooes = input.next();
            if (chooes.equalsIgnoreCase("N")){
                out.close();
                System.out.println("程序退出!");
                break;
            }else {
               out.write(chooes.getBytes(StandardCharsets.UTF_8));
                System.out.println("发送成功");
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值