手机端下载文件时显示0B问题

下载文件时显示文件大小

设置下载文件的大小


        File file=new File("D:/test.txt");
        response.setHeader("Accept-Ranges","bytes");
        response.setHeader("Content-Length",file.length()+"");

完整小例子

 /**
     * 下载文件
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping("/downloadFile")
    public void downloadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/octet-stream");
        File file = new File("D://test3//DGSetup_Home_KZ.exe");

        /**
         * 设置header头显示下载文件的大小
         */
        response.setHeader("Accept-Ranges", "bytes");
        response.setHeader("Content-Length", file.length() + "");

        String fileName = URLEncoder.encode("DGSetup_Home_KZ.exe", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);

        try {
            FileInputStream in = new FileInputStream(file);
            // 创建输出流
            OutputStream out = response.getOutputStream();
            // 创建缓冲区
            byte buffer[] = new byte[1024];
            int len = 0;
            // 循环将输入流中的内容读取到缓冲区当中
            while ((len = in.read(buffer)) > 0) {
                // 输出缓冲区的内容到浏览器,实现文件下载
                out.write(buffer, 0, len);
            }
            // 关闭文件输入流
            in.close();
            // 关闭输出流
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

可以看到下载时显示了文件的大小,在手机端同样也有同样作用,手机端确认下载前,会提示文件的大小。
在这里插入图片描述

如果是OutputStream输出流,如何设置大小

直接使用response.getOutputStream输出流进行输出时,是不能获取输出流或者输出文件的大小。
解决办法也有很多

  • 方法1(略) 将输出流写入临时文件,再File对象的length方法获取文件大小;缺点,需要使用到临时文件,存在频繁的磁盘操作
  • 方法2(如下示例) 不直接输出到response.getOutputStream,先利用ByteArrayOutputStream接收,再使用ByteArrayInputStream 读取,使用InputStream的available方法获取输出流的字节大小。然后再输出到response.getOutputStream
try {
            /**
             *直接将输出流输出到response.getOutputStream时,前端无法显示下载文件的大小,可以通创建ByteArrayOutputStream接收,
             * 再利用ByteArrayInputStream读取,再输出到response.getOutputStream流,这样可以支持显示文件的大小,但是不适合较大文件,
             * 因为数据流存储在内容中,经过一次转换才转发出去
             *
             */
            //PdfUtil.output(templateFile, dataMap, picMap, checkboxMap, response.getOutputStream());
            ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
            PdfUtil.output(templateFile, dataMap, picMap, checkboxMap, outputStream);
            ByteArrayInputStream in=new ByteArrayInputStream(outputStream.toByteArray());
            response.setHeader("Accept-Ranges", "bytes");
            response.setHeader("Content-Length", in.available() + "");
//            FileInputStream in = new FileInputStream(file);
            // 创建输出流
            OutputStream out = response.getOutputStream();
            // 创建缓冲区
            byte buffer[] = new byte[1024];
            int len = 0;
            // 循环将输入流中的内容读取到缓冲区当中
            while ((len = in.read(buffer)) > 0) {
                // 输出缓冲区的内容到浏览器,实现文件下载
                out.write(buffer, 0, len);
            }
            // 关闭文件输入流
            in.close();
            // 关闭输出流
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

扩展问题

pdfjs预览pdf文件时遇到的问题

使用pdfjs预览pdf文件时,不要返回文件大小,因为pdfjs会判断文件的长度,会发生控制台错误,文件大小不一致,所以建议在预览时不返回长度给前端,只有文件下载时返回文件的大小。

在这里插入图片描述

完整示例

 /**
     * 下载文件、预览文件
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping("/downloadFile")
    public void downloadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/octet-stream");
        File file = new File("D://test3//abc.pdf");

        /**
         * 设置header头显示下载文件的大小
         */
        String showType=request.getParameter("showType"); //download 下载,preview下载
        if(showType.equals("download")){
            response.setHeader("Accept-Ranges", "bytes");
            response.setHeader("Content-Length", file.length() + "");
            String fileName = URLEncoder.encode("abc.pdf", "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        }else{
            String fileName = URLEncoder.encode("abc.pdf", "UTF-8");
            response.setHeader("Content-Disposition", "inline;filename=" + fileName);
        }

        try {
            FileInputStream in = new FileInputStream(file);
            // 创建输出流
            OutputStream out = response.getOutputStream();
            // 创建缓冲区
            byte buffer[] = new byte[1024];
            int len = 0;
            // 循环将输入流中的内容读取到缓冲区当中
            while ((len = in.read(buffer)) > 0) {
                // 输出缓冲区的内容到浏览器,实现文件下载
                out.write(buffer, 0, len);
            }
            // 关闭文件输入流
            in.close();
            // 关闭输出流
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值