文件上传案例阻塞问题以及案例优化

文件上传案例阻塞问题

解决:上传完文件,给服务器写一个结束标记

void shutdownOutput() 禁用此套接字的输出流

对于TCP套接字,任何以前写入的数据都将被发送,并且后跟TCP的正常连接终止序列

复制代码
public class TCPClient {
    public static void main(String[] args) throws IOException {
        //1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
        FileInputStream fis = new FileInputStream("G:\\图片\\1.png");
        //2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
        Socket socket = new Socket("127.0.0.1", 8888);
        //3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
        byte[] bytes = new byte[1024];
        int len;
        while ((len=fis.read(bytes))!=-1){
            //5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传到服务器
            os.write(bytes,0,len);
        }
        socket.shutdownOutput();
        //6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();
        //7.使用网络字节输入流InputStream对象中的方法read读取服务回写的数据
        while ((len=is.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len));
        }
        //8.释放资源(FileInputStream,Socket)
        fis.close();
        socket.close();
    }
}
复制代码

 

 

 

 

 

 

 

 

 

 

 

文件上传案例优化

自定义一个文件的命名规则:
防止同名的文件被覆盖
规则:域名+毫秒值+随机数
复制代码
public class TCPServer {
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器ServerSocket对象,和系统要指定的端口号
        ServerSocket server = new ServerSocket(8888);
        //2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象
        Socket socket = server.accept();
        //3.使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();
        //4.判断d:\\upload文件夹是不是存在,不存在则创建
        File file = new File("G:\\upload");
        if (!file.exists()){
            file.mkdirs();
        }

        /**
         * 自定义一个文件的命名规则:防止同名的文件被覆盖
         * 规则:域名+毫秒值+随机数
         */
        String filename = "itcast"+System.currentTimeMillis()+new Random().nextInt(999999)+".png";


        //5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地
//        FileOutputStream fos = new FileOutputStream(file+"\\a.png");
        FileOutputStream fos = new FileOutputStream(file+"\\"+filename);
        //6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
        byte[] bytes = new byte[1024];
        int len;
        while ((len=is.read(bytes))!=-1){
            //7.使用本地字节输出流FileOutputStream对象中的方法write,把读取的文件保存到服务器的硬盘上
            fos.write(bytes,0,len);
        }
        //8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写“上传成功”
        os.write("上传成功".getBytes());
        //10.释放资源(FileOutputStream,Socket,ServerSocket)
        fos.close();
        socket.close();
        server.close();
    }
}
复制代码

 

循环接收

让服务器一直处于监听状态(死循环accept方法)

有一个客户端上传文件,就保存一个文件

复制代码
public class TCPServer {
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器ServerSocket对象,和系统要指定的端口号
        ServerSocket server = new ServerSocket(8888);
        //2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象

        /**
         *让服务器一直处于监听状态(死循环accept方法)
         * 有一个客户端上传文件,就保存一个文件
         */
        while (true) {
            Socket socket = server.accept();
            //3.使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象
            InputStream is = socket.getInputStream();
            //4.判断d:\\upload文件夹是不是存在,不存在则创建
            File file = new File("G:\\upload");
            if (!file.exists()) {
                file.mkdirs();
            }

            /**
             * 自定义一个文件的命名规则:防止同名的文件被覆盖
             * 规则:域名+毫秒值+随机数
             */
            String filename = "itcast" + System.currentTimeMillis() + new Random().nextInt(999999) + ".png";


            //5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地
//        FileOutputStream fos = new FileOutputStream(file+"\\a.png");
            FileOutputStream fos = new FileOutputStream(file + "\\" + filename);
            //6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
            byte[] bytes = new byte[1024];
            int len;
            while ((len = is.read(bytes)) != -1) {
                //7.使用本地字节输出流FileOutputStream对象中的方法write,把读取的文件保存到服务器的硬盘上
                fos.write(bytes, 0, len);
            }
            //8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象
            OutputStream os = socket.getOutputStream();
            //9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写“上传成功”
            os.write("上传成功".getBytes());
            //10.释放资源(FileOutputStream,Socket,ServerSocket)
            fos.close();
            socket.close();
        }
        //服务器就不需要关闭
//        server.close();
    }
}
复制代码

使用多线程提高效率

有一个客户端上传文件,就开启一个线程,完成文件的上传

复制代码
public class TCPServer {
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器ServerSocket对象,和系统要指定的端口号
        ServerSocket server = new ServerSocket(8888);
        //2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象

        /**
         *让服务器一直处于监听状态(死循环accept方法)
         * 有一个客户端上传文件,就保存一个文件
         */
        while (true) {
            Socket socket = server.accept();
            /**
             * 使用多线程提高效率
             * 有一个客户端上传文件,就开启一个线程,完成文件的上传
             */
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //3.使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象
                        InputStream is = socket.getInputStream();
                        //4.判断d:\\upload文件夹是不是存在,不存在则创建
                        File file = new File("G:\\upload");
                        if (!file.exists()) {
                            file.mkdirs();
                        }

                        /**
                         * 自定义一个文件的命名规则:防止同名的文件被覆盖
                         * 规则:域名+毫秒值+随机数
                         */
                        String filename = "itcast" + System.currentTimeMillis() + new Random().nextInt(999999) + ".png";


                        //5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地
                        //FileOutputStream fos = new FileOutputStream(file+"\\a.png");
                        FileOutputStream fos = new FileOutputStream(file + "\\" + filename);
                        //6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
                        byte[] bytes = new byte[1024];
                        int len;
                        while ((len = is.read(bytes)) != -1) {
                            //7.使用本地字节输出流FileOutputStream对象中的方法write,把读取的文件保存到服务器的硬盘上
                            fos.write(bytes, 0, len);
                        }
                        //8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象
                        OutputStream os = socket.getOutputStream();
                        //9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写“上传成功”
                        os.write("上传成功".getBytes());
                        //10.释放资源(FileOutputStream,Socket,ServerSocket)
                        fos.close();
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
        //服务器就不需要关闭
//        server.close();
    }
}
复制代码

 

posted @   xjw12345  阅读(139)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示