开发者社区> 问答> 正文

java web 多线程下载文件的问题。?报错

当我开启多线程下载文件时,outputstream.write   循环两轮后 报 空指针 错误。 大佬们帮我看看

 ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(
                new Runnable() {
                    @Override
                    public void run() {
                        String path=System.getProperty("catalina.home")+"/webapps/uploadFiles/njhb/areaFiles/南京市/"+fileName;
                        final File file  = new File(path);
                        if(!file.exists()){
                            System.out.println("文件不存在");
                            //response.setHeader("content-type", "text/html;charset=UTF-8");
                            response.setContentType("text/html;charset=UTF-8");
                            PrintWriter writer = null;
                            try {
                                writer = response.getWriter();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            writer.write("文件不存在!");
                            return;
                        }
                        response.reset();
                        response.setCharacterEncoding("UTF-8");
                        response.setContentType("multipart/form-data");
                        response.setHeader("Content-Disposition",
                                "attachment;fileName="+ encodingFileName(fileName));
                        response.setHeader("Set-Cookie", "fileDownload=true; path=/;" +
                                "attachment;fileName=" + encodingFileName(fileName));

                        try {
                            //打开本地文件流
                            InputStream inputStream = new FileInputStream(file);
                            //激活下载操作
                            OutputStream outputStream = response.getOutputStream();

                            //循环写入输出流  每次读取2048  一直读完
                            byte[] b = new byte[2048];
                            int length;
                            int count=0;
                            while ((length = inputStream.read(b)) > 0) {
                                System.out.println("b: "+b+"     length: "+length);
                                //这行 循环两轮后  空指针
                                outputStream.write(b, 0, length);
                                count++;
                            }

                            // 这里主要关闭。
                            outputStream.close();
                            inputStream.close();





                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                            logg.info("文件下载终止!!!");
                        }
                    }
                }
        );

 

报错信息如下:

 

 

展开
收起
爱吃鱼的程序员 2020-06-05 16:03:29 719 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB
                        <p>线程安全哦,使用 ThreadLocal定义length</p>
                    
    
                            不对呀 哥,改了 还是 空指针异常
                        
    
                        <p>outputStream不需要自己close,因为它不是你new出来的,而是从response对象获取的。另外你这个close也应该放到finally,不然异常之后怎么释放资源?length的定义我觉得没问题,本身在线程处理方法里定义的,不存在线程安全问题。</p>
                    
    
                            哥 到底是什么问题。
                        
    
                        <p>这段代码有两个问题,</p> 
    

    1.while循环条件的判断,应该用-1.

        因为fileInputStream的read方法只有在返回-1的时候,才会认为到达文件末尾的

        

    2.异步任务不是这个用法

    你开起了一个线程使用了tomcat封装的response,当你start后,这个方法就已经return,tomcat就认为这个请求已经结束了,会释放掉这个socket。

    如果你的文件大,就会出现tomcat已经关闭了对应的socket会话,你线程里持有的response已经失效了,所有outputStream也已经为null了。

    所以不建议你使用这种异步的形式下载文件

    2020-06-05 16:03:43
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载