通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)

这篇具有很好参考价值的文章主要介绍了通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.单文件下载

1.简单理解文件下载

文件下载,是从服务器下载到本地电脑。 文件下载的原理,首先通过IO流将服务器的文件读取到内存里(只有将数据读到内存,电脑才可以操作数据),读取后文件数据存放在内存中,将内存中的数据通过网络发送给本地客户端的浏览器。本地客户端的浏览器接受数据,并在本地生成对应的文件。
通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)

通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)

2.单文件下载的具体代码实现

  • 接受请求,参数 path是文件在服务器的路径(通常路径会存在sql表里,通过查表获取,这里是为了测试),HttpServletResponse 要通过HttpServletResponse来实现客户端和服务器通信的响应部分(将响应头和文件数据返回后端)。
 @RequestMapping("/download")
    public  void downLoad(String path, HttpServletResponse response) throws UnsupportedEncodingException {
  • 设置响应头信息(规定死的)
    响应头信息代表的含义:
    • ContentType ,互联网媒体类型,也叫做MIME类型,Http在传输数据对象时会为他们打上MIME的数据格式标签,区分数据类型
      常见ContentType,
    • text/html ,HTML文本
    • application/json , 键值对的json数据格式
    • application/octet-stream ,是一种二进制数据流的文件类型,通常用于文件传输。它表示文件中包含的数据是二进制数据,而不是文本。由于它是一种通用类型,因此它可用于处理各种类型的文件,如图像,音频和视频文件。
    • Content-Disposition
      指定响应头的展示方式,主要体现在:
      * 指定下载文件的文件名和保存方式。如"attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")中的filename=xxx指定了后的文件的文件名和格式
      * 控制浏览器的行为。如"attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")attachment,指定浏览器以附件的形式展示文件,即指定浏览器下载文件而不是打开文件,如果设置为inline,则是在浏览器打开文件。如果没有filename 浏览器会出现保存为的对话框。
    • 常见值
Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="XXX"
 * 设置响应头代码
        response.reset();
        response.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
        response.setCharacterEncoding("utf-8");//设置编码格式为utf-8
        response.setContentLength((int)file.length());//响应数据长度
        response.setContentType("application/octet-stream");
  • 通过IO流读取文件并将数据返回给浏览器
    try(BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));OutputStream outputStream = response.getOutputStream();)是try-with-resource的语法格式,作用为try块退出时,会自动调用在()中的bisoutputStream资源的close()方法,自动关闭IO资源。(不用手动关闭了代码书写复杂度降低)
    获取response的输出流OutputStream,从文件的InputStream输入流读取数据到内存,然后通过输出流写入。
    通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)

    • 代码示例
try(BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));OutputStream  outputStream = response.getOutputStream();)
        {

            byte[] bytes = new byte[1024];
            int i=0;
            while((i=bis.read(bytes))!=-1)
            {
                outputStream.write(bytes,0,i);
            }
        }catch (Exception e)
        {
            e.printStackTrace();
        }

3.测试

通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)

4.单文件下载整体代码

 @RequestMapping("/download")
    public  void downLoad(String path, HttpServletResponse response) throws UnsupportedEncodingException {

        File file=new File(path);
        String fileName= file.getName();

        response.reset();
        response.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
        response.setCharacterEncoding("utf-8");
        response.setContentLength((int)file.length());
        response.setContentType("application/octet-stream");
        System.out.println("filename:"+fileName);
        try(BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));OutputStream  outputStream = response.getOutputStream();)
        {

            byte[] bytes = new byte[1024];
            int i=0;
            while((i=bis.read(bytes))!=-1)
            {
                outputStream.write(bytes,0,i);
            }
        }catch (Exception e)
        {
            e.printStackTrace();
        }

    }

二.多文件批量下载(多个文件合成一个压缩包下载)

1.多文件下载的实现方式,这里使用了ZipOutputStream

  • 介绍ZipOutputStream
    • ZipOutputStream使用流程,
      通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)

    • 使用示例

//初始化,test.zip是写入压缩包的名称
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream("test.zip"));
//创建一个名称为test.txt新的条目,一般压缩包中有很多文件,新条目相当于创建新文件
zipOutputStream.putNextEntry(new ZipEntry("test.txt"));
//写入具体内容
zipOutputStream.write("Hello World".getBytes());
//关闭条目
zipOutputStream.closeEntry();
//关闭整体压缩输出流
zipOutputStream.close();

2.具体代码实现

  • 模拟选中多文件(可以通过前端传)
  List<String> pathList=new ArrayList<>();
        pathList.add("xxx.txt");
        pathList.add("xxx.txt");
        pathList.add("xxx.txt");
  • 设置响应头
   response.reset();
        response.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode("1.zip", "UTF-8"));
        response.setCharacterEncoding("utf-8");
  • 初始化ZipOutputStream
try(ZipOutputStream zipOutputStream=new ZipOutputStream(new BufferedOutputStream(response.getOutputStream())))
  • 遍历List,从中读取要批量下载的文件路径
     for(String pathName:pathList)
  • 对每个批量下载的文件,都在zipOutputStream(压缩包中创建对应的条目,及对应的文件)putNextEntry(new ZipEntry(fileName))创建和下载文件相同名称的文件条目。把每个下载的文件内容写入到zipOutputStream中的条目中,关闭条目,然后循环。

   
                File file =new File(pathName);
                String fileName=file.getName();
                zipOutputStream.putNextEntry(new ZipEntry(fileName));
                try(BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file))){
                    byte[] bytes = new byte[1024];
                    int i=0;
                    while((i=bis.read(bytes))!=-1)
                    {
                        zipOutputStream.write(bytes,0,i);
                    }
                    zipOutputStream.closeEntry();
               

3.测试

通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)

4.文件批量下载(多文件合成一个压缩包)完整代码

@GetMapping("/downloadlist")
    public void downLoadList(  HttpServletResponse response ) throws UnsupportedEncodingException {

        List<String> pathList=new ArrayList<>();
        pathList.add("xxx.txt");
        pathList.add("xxx.txt");
        pathList.add("xxx.txt");

        response.reset();
        response.setHeader("Content-Disposition","attachment; filename=" + URLEncoder.encode("1.zip", "UTF-8"));
        response.setCharacterEncoding("utf-8");

        response.setContentType("application/octet-stream");

        try(ZipOutputStream zipOutputStream=new ZipOutputStream(new BufferedOutputStream(response.getOutputStream())))
        {
            for(String pathName:pathList)
            {
                File file =new File(pathName);
                String fileName=file.getName();
                zipOutputStream.putNextEntry(new ZipEntry(fileName));
                try(BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file))){
                    byte[] bytes = new byte[1024];
                    int i=0;
                    while((i=bis.read(bytes))!=-1)
                    {
                        zipOutputStream.write(bytes,0,i);
                    }
                    zipOutputStream.closeEntry();
                }catch (Exception e)
                {
                    e.printStackTrace();
                }
            }

        }catch (Exception e)
        {
            e.printStackTrace();
        }
    }

三.补充,将整个文件夹压缩

1.将一个文件夹压缩,这个文件夹中全是具体文件

关键点在ZipOutputStream中putNextEntry() 方法上,putNextEntry()相当于往压缩包中加入子文件(也可以是子文件夹),new ZipEntry(fileName)是建立的子文件(或文件夹),如果

  • fileNamea.txtxx.pdf相当于直接创建子文件放入压缩包
  • fileNameddd/a.txt 则会在压缩包中创建一个为ddd的文件夹,ddd文件夹下创建a.txt
  zipOutputStream.putNextEntry(new ZipEntry(fileName));

实际解决思路,如果要将一个文件夹下的多个文件压缩,实际效果为点开压缩包,里面有个文件夹,文件夹下是多个文件
解决,

  • 创建一个压缩包,对应了new ZipOutputStream
  • 有了这个压缩包,需要在创建压缩包里的文件,对应了new ZipEntry(fileName),若参数fileName带路径,则会创建带文件夹的文件
  • 将创建的文件加入压缩包,putNextEntry(new ZipEntry(fileName))
  • 将要文件数据写入到要压缩包中的文件中
    总的来说是,操作每个文件的时候要保留前面文件夹的路径,fileName必须是ddd/a.txt,这样才会在压缩包中有文件夹

2.将整个文件夹压缩,文件中包含文件夹

解决,
判断是文件夹还是文件,如果是文件夹,则将文件夹名称记录传给子文件,如果是文件,传过来的文件夹和文件名,在压缩包中创建对应的文件夹名和文件名,然后将数据复制给压缩包中的文件

总的来说,压缩文件或文件夹是通过fileName参数在压缩包中创建文件夹或文件,然后将数据拷贝给压缩包中的文件一份
通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)文章来源地址https://www.toymoban.com/news/detail-476181.html

到了这里,关于通俗易懂【Springboot】 单文件下载和批量下载(多个文件合成一个压缩包下载)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot整合hdfs,实现文件上传下载删除与批量删除,以及vue前端发送请求,实现前后端交互功能;

    部分工具类代码参考文章:https://blog.csdn.net/qq_27242695/article/details/119683823 前端实现效果 HDFSController HDFS FileInterface (文件接口) HDFS FileImplService (文件接口实现类) HDFSConfig(从yaml读取文件) HDFSUTils 前端vue代码:

    2024年02月16日
    浏览(79)
  • 文件夹的批量下载

            公司想实现文件系统下载,上次图简单就草率的写了文件下载,这不趁着同事请假赶集吧这坑给填上。                   刚准备开始写,就头疼,文件只要获得数据输出流就行,但是这文件夹需要维护层级关系。         前端给的是服务器的绝对地址,还得服务

    2024年02月11日
    浏览(44)
  • 【Java】对Minio指定Bucket大量文件的批量下载与本地文件夹的批量上传

    需要批量下载一个bucket下的内容,bucket下文件有19GB+,且文件夹结构复杂,使用官方的Console无法完成这么大量文件的下载,而且也不支持文件夹的分享,所以自己写个工具下载,顺便把上传的也写了。 使用官方的打包下载,由于文件太多,一直转,而且session一失效,或者刷

    2024年02月09日
    浏览(53)
  • java 批量下载文件 打包成zip包

    创建DownLoadUrlStream承载数据 创建工具类,进行zip包压缩 封装数据,调用方法即可

    2024年02月12日
    浏览(40)
  • Java实现打包压缩文件或文件夹生成zip以实现多文件批量下载

    有时候在系统中需要一次性下载多个文件,但逐个下载文件比较麻烦。这时候,最好的解决办法是将所有文件打包成一个压缩文件,然后下载这个压缩文件,这样就可以一次性获取所有所需的文件了。 下面是一个名为CompressUtil的工具类的代码,它提供了一些方法来处理文件压

    2024年02月06日
    浏览(57)
  • 百度智能云对象存储BOS批量下载文件方法

    百度智能云对象存储BOS支持批量打包下载吗?目前对象存储BOS浏览器端不支持批量下载,可以使用对象存储BOS桌面或BOSCMD批量下载,也可以使用API/SDK调用接口循环下载。新手站长网来详细说下百度云对象存储BOS批量下载的方法: 目录 百度云对象存储BOS批量下载 BOS桌面客户端

    2023年04月20日
    浏览(35)
  • Python批量下载ts视频文件,并用ffmpeg合并

    目录 一、ts文件的由来 二、下载ts文件 1.下载index.m3u8,并做相应处理 2.下载ts文件 三、ffmpeg合并ts文件 ts文件,ts即\\\"Transport Stream\\\"的缩写,特点就是要求从视频流的任一片段开始都是可以独立解码的,非常适合网络视频播放。 打开网址:https://www.kan35.com/play/210314-3-1.html,要怎

    2024年01月20日
    浏览(59)
  • 如何批量下载hugging face模型和数据集文件

    目前网上关于下载hugging face模型文件大多都是一个一个下载,无法做到批量下载,但有些模型或数据集包含文件太多,不适用一个一个下载。本文将会介绍如何使用git进行批量下载。 由于Hugging Face的部分模型和数据集在国外服务器,不使用代理比较慢,所以要先配置git代理。

    2024年02月11日
    浏览(47)
  • php压缩一个文件夹,php下载多个图片

    把 100/ 这个文件夹,压缩成 一百.zip 然后得到zip所在的下载url 这个功能,需要PHP去掉禁用函数 shell_exec  

    2024年02月11日
    浏览(55)
  • 致远OA SQL&任意文件下载漏洞(含批量检测POC)

    致远OA A6 test.jsp 存在sql注入漏洞,并可以通过注入写入webshell文件控制服务器 漏洞影响 致远OA A6 网络测绘 app=“致远OA6” 批量检测POC 当然扫描结果可能不是特别准确,可能因素是网络测绘工具根据语法收集的ip有出入,或者有waf检测到恶意流量跳转到防护页面等,状态码也是

    2024年02月07日
    浏览(63)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包