Java下载小文件正常,大文件总是404错误

最近处理文件下载遇到奇怪的现象:小文件(30 ~ 40M)下载正常,大文件(>100M)下载总是404 

因为使用了Nginx,最初怀疑是代理配置的问题,于是

proxy_buffering off

或
proxy_buffering on;
proxy_buffers 4 4k;
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 1024m;

并
proxy_send_timeout 600;
proxy_read_timeout 600;

 结果没卵用,再细想404 是服务报出来的,于是专心改代码

 

最初代码如下

下载fn.docx 
    @RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
    @ResponseBody
    public void downloadFile(HttpServletRequest request, HttpServletResponse response) {
        try {
            String fileName = new String(
                    request.getParameter("fileName").getBytes("iso-8859-1"),
                    "UTF-8"
            );
            String filePath = new String(
                    request.getParameter("filePath").getBytes("iso-8859-1"),
                    "UTF-8"
            );

            File file = new File(filePath);
            if (!file.exists()) {
                return;
            }

            InputStream input = new FileInputStream(file);
            byte[] buffer = new byte[input.available()];
            input.read(buffer);
            input.close();

            response.reset();
            response.setHeader(
                "Content-disposition", 
                "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")
            );
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");

            OutputStream output = response.getOutputStream();
            output.write(buffer);
            output.flush();
            output.close();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

 

改成如下代码就好了

    @RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
    @ResponseBody
    public void downloadFile(HttpServletRequest request, HttpServletResponse response) {
        BufferedInputStream input = null;
        BufferedOutputStream output = null;
        try {
            String fileName = new String(
                    request.getParameter("fileName").getBytes("iso-8859-1"),
                    "UTF-8"
            );
            String filePath = new String(
                    request.getParameter("filePath").getBytes("iso-8859-1"),
                    "UTF-8"
            );

            File file = new File(filePath);
            if (!file.exists()) {
                return;
            }

            input = new BufferedInputStream(new FileInputStream(file));

            response.setHeader(
                    "Content-disposition",
                    "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")
            );
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");

            ServletOutputStream servlet = response.getOutputStream();
            output = new BufferedOutputStream(servlet);

            byte[] buffer = new byte[2048];
            int len = 0;
            while ((len = input.read(buffer, 0, buffer.length)) != -1) {
                output.write(buffer, 0, len);
            }
            output.flush();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            try {
                if (null != output) {
                    output.close();
                }
                if (null != input) {
                    input.close();
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

 

我只是知其然,不知道所以然,不明白

ServletOutputStream 和 OutputStream 有啥区别?

你可能感兴趣的:(程序/Bug解决)