关键词搜索

源码搜索 ×
×

一篇文章带你搞定 Java 网络编程中的文件上传下载案例优化

发布2020-03-09浏览542次

详情内容

一、文件上传优化分析

  1. 客户端服务端关闭的问题
 /*
问题:客户端和服务器都无法终止,遇到了阻塞
原因:这里未读取到-1,也就是未给服务器写一个结束标记
解决:上传完文件,给服务器写一个结束标记
void shutdownOutput() 禁用此套接字的输出流。
对于 TCP 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。
*/
socket.shutdownOutput();//给服务器写结束标记,这样服务器才能正常终止
    1. 文件名称写死的问题
      服务端,保存文件的名称如果写死,那么最终导致服务器硬盘,只会保留一个文件,建议使用系统时间优化,保证文件名称唯一,代码如下:
    FileOutputStream fis = new FileOutputStream(System.currentTimeMillis()+".jpg") // 文件名称
    BufferedOutputStream bos = new BufferedOutputStream(fis);
    
    • 1
    • 2
    1. 循环接收的问题
      服务端,指保存一个文件就关闭了,之后的用户无法再上传,这是不符合实际的,使用循环改进,可以不断的接收不同用户的文件
    // 每次接收新的连接,创建一个Socket
    whiletrue{
        Socket accept = serverSocket.accept();
        ......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 效率问题
      服务端,在接收大文件时,可能耗费几秒钟的时间,此时不能接收其他用户上传,所以,使用多线程技术优化。
    whiletrue{
        Socket accept = serverSocket.accept();
        // accept 交给子线程处理.
        new Thread(() -> {
          	......
            InputStream bis = accept.getInputStream();
          	......
        }).start();
    }
    
      9

    二、优化代码实现

    class FileUpload_Thread implements Runnable{
        private Socket socket;
        private File file;
        public FileUpload_Thread(Socket accept,File f){
            socket = accept;
            file = f;
        }
        //完成文件的上传
        @Override
        public void run() {
            try{
            //3.使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象
                InputStream is = socket.getInputStream();
                /*
                            自定义一个文件的命名规则:防止同名的文件被覆盖
                            规则:域名+毫秒值+随机数
               */
                String fileName = "File" + new Random().nextInt(99999) + ".jpg";
                   //5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地
                FileOutputStream fos = new FileOutputStream(file + "\\" + fileName);
                int len = 0;
                byte[] bytes = new byte[1024];
                while ((len = is.read(bytes))!=-1){
                 //7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上
                    fos.write(bytes,0,len);
                }
                //8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象
               //9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写"上传成功"
                socket.getOutputStream().write("上传成功".getBytes());
                //10.释放资源(FileOutputStream,Socket,ServerSocket)
                fos.close();
                socket.close();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    public class FileUpload_Server {
        public static void main(String[] args) throws IOException {
        //1.创建一个服务器ServerSocket对象,和系统要指定的端口号
            ServerSocket server = new ServerSocket(8888);
            File file = new File("E:\\upload");
            if(!file.exists()) file.mkdirs();
    		/https://files.jxasp.com/image/2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象
    
            /*
                让服务器一直处于监听状态(死循环accept方法)
                有一个客户端上传文件,就保存一个文件
             */
            while(true){
                Socket socket = server.accept();
                /*
                    使用多线程技术,提高程序的效率
                    有一个客户端上传文件,就开启一个线程,完成文件的上传
                 */
                FileUpload_Thread ft = new FileUpload_Thread(socket,file);
                Thread t = new Thread(ft);
                t.start();
            }
        }
    }
    
    
      9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    相关技术文章

    点击QQ咨询
    开通会员
    返回顶部
    ×
    微信扫码支付
    微信扫码支付
    确定支付下载
    请使用微信描二维码支付
    ×

    提示信息

    ×

    选择支付方式

    • 微信支付
    • 支付宝付款
    确定支付下载