当前位置: 首页 > news >正文

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

文章目录

  • 一.单文件下载
      • 1.简单理解文件下载
      • 2.单文件下载的具体代码实现
      • 3.测试
      • 4.单文件下载整体代码
  • 二.多文件批量下载(多个文件合成一个压缩包下载)
      • 1.多文件下载的实现方式,这里使用了ZipOutputStream
      • 2.具体代码实现
      • 3.测试
      • 4.文件批量下载(多文件合成一个压缩包)完整代码

一.单文件下载

1.简单理解文件下载

文件下载,是从服务器下载到本地电脑。 文件下载的原理,首先通过IO流将服务器的文件读取到内存里(只有将数据读到内存,电脑才可以操作数据),读取后文件数据存放在内存中,将内存中的数据通过网络发送给本地客户端的浏览器。本地客户端的浏览器接受数据,并在本地生成对应的文件。
在这里插入图片描述

在这里插入图片描述

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-8response.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输入流读取数据到内存,然后通过输出流写入。
    在这里插入图片描述

    • 代码示例
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.测试

在这里插入图片描述

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使用流程,
      在这里插入图片描述

    • 使用示例

//初始化,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.测试

在这里插入图片描述

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();}}

相关文章:

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

文章目录一.单文件下载1.简单理解文件下载2.单文件下载的具体代码实现3.测试4.单文件下载整体代码二.多文件批量下载&#xff08;多个文件合成一个压缩包下载&#xff09;1.多文件下载的实现方式&#xff0c;这里使用了ZipOutputStream2.具体代码实现3.测试4.文件批量下载&…...

CnOpenData中国行政区划shp数据

一、数据简介 中国行政区划数据是重要的基础地理信息数据&#xff0c;目前不同来源的全国行政区划数据非常多&#xff0c;但能够开放获取的高质量行政区域数据少之又少。基于此&#xff0c;锐多宝的地理空间制作一套2013-2023年可开放获取的高质量行政区划数据。该套数据以2022…...

GPT-4零失误通关大厂模拟面试,offer拿到手软?与AGI首次接触

来源: FoxyearMeta “GPT-4可被视作AGI &#xff08;通用人工智能&#xff09;的早期版本。” 如若从他人口中说出&#xff0c;或许是无稽之谈—— 但是由微软雷蒙德研究院机器学习理论组负责人万引大神Sbastien Bubeck与2023新视野数学奖得主Ronen Eldan、2023新晋斯隆研究奖得…...

Hardhat 环境搭建及教程示例

一.安装node.js curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash nvm install 18 nvm use 18 nvm alias default 18 npm install npm --global # Upgrade npm to the latest version 二. 安装hardhat 2.1 创建hardhat安装目录 mkdir hard…...

复杂链表的复制-剑指Offer35-java

一、题目描述 请实现 copyRandomList 函数&#xff0c;复制一个复杂链表。在复杂链表中&#xff0c;每个节点除了有一个 next 指针指向下一个节点&#xff0c;还有一个 random 指针指向链表中的任意节点或者 null。 示例 1&#xff1a; 输入&#xff1a;head [[7,null],[13,…...

【Linux】进程理解与学习Ⅰ-进程概念

环境&#xff1a;centos7.6&#xff0c;腾讯云服务器Linux文章都放在了专栏&#xff1a;【Linux】欢迎支持订阅&#x1f339;相关文章推荐&#xff1a;【Linux】冯.诺依曼体系结构与操作系统进程概念什么是进程&#xff1f;进程是什么&#xff1f;我们打开任务管理器可以看到有…...

WebKitX ActiveX 6.0 X86 Crack

WebKitX ActiveX将 Chromium Embedded Framework (CEF3) 包装到一个进程外的 ActiveX 组件中&#xff0c;以便与 OLE/COM 语言一起使用。Chromium Embedded Framework 封装了 WebKit Blink HTML5 Renderer 和 Google V8 JavaScript Engine。这是一个用于商业用途的生产级稳定组…...

开源项目:数据库表结构生成文档工具

目录 一、软件介绍 二、技术框架 三、功能介绍 四、代码展示 1、获取数据库信息部分代码 2、导出Html文档代码 五、运行效果 六、项目开源地址 一、软件介绍 今天给大家分享我自己编写的数据库表结构文档生成工具&#xff0c;方便大家在实际开发当中&#xff0c;可以很方便导出…...

spring的两种拦截器HandlerIntercepter和MethodIntercepter

介绍 Spring有两种拦截器提供给我们使用&#xff0c;一种是HandlerIntercepter&#xff0c;另一种是MethodIntercepter。这两种的来源不同&#xff0c;实现方式也不同&#xff0c;具体的下面来看一下。 HandlerIntercepter 来源 来源于spring-webmvc包 HandlerIntercepter拦…...

初级算法-字符串

主要记录算法和数据结构学习笔记&#xff0c;新的一年更上一层楼&#xff01; 初级算法-字符串一、反转字符串二、反转字符串&#xff08;二&#xff09;三、替换空格四、翻转字符串里的单词五、左旋转字符串六、实现 strStr()七、重复的子字符串字符串中元素只能是字符String…...

华为OD机试题 - 寻找目标字符串(JavaScript)| 机考必刷

更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为…...

删除Terminating状态的namespace:cattle-system

这里以cattle-system为例&#xff01;执行删除命令后namespace&#xff08;也是用其他k8s object&#xff09;仍然存在&#xff0c;首先执行 kubectl edit namespace cattle-system 查看是否存在spec.finalizers: kubernetes&#xff0c;如&#xff1a; spec: finalizers:…...

MiniOB 并发B+树实现解析

MiniOB 是 OceanBase 联合华中科技大学推出的一款用于教学的小型数据库系统&#xff0c;希望能够帮助数据库爱好者系统性的学习数据库原理与实战。 B 树介绍 B 树是传统数据库中常见的索引数据结构&#xff0c;比如MySQL、PostgreSQL都实现了B树索引。B 树是一个平衡多叉树&am…...

SpringCloud负载均衡服务调用——Ribbon

Ribbon 本专栏学习内容来自尚硅谷周阳老师的视频 有兴趣的小伙伴可以点击视频地址观看 简介 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。 简单的说&#xff0c;Ribbon是Netflix发布的开源项目&#xff0c;主要功能是提供客户端的软件负载均衡算…...

各种邮箱服务软件对比

1.宝塔邮局管理器 特点:简单易用,可视化操作,小白也能搞,还有备份功能,一般足够用了 缺点:稳定性真是差,隔三差五的不能收发.没有接口,不能任意修改邮箱密码,只能管理员修改 注意要点:一定要开启ssl,否则有些邮箱给你发邮件你收不到 建议:不要入坑.坏了之后没法修复,哭都没地方…...

相机单独标定的实现过程[autoware标定]、tmp文件的查看方式

安装了autoware1.13和calibration标定包&#xff0c;发现实现相机单独标定的过程较为坎坷&#xff0c;参考了一些博主的方法&#xff0c;发现下面的过程更加适合自己&#xff0c;做个笔记。 1安装标定箱&#xff08;与calibration标定包的安装并不冲突&#xff09; 标定工具箱…...

4.10.1、IP 多播技术的相关基本概念

多播&#xff08;Multicast&#xff0c;也称为组播&#xff09;是一种实现 “一对多” 通信的技术&#xff0c;与传统单播“一对一”通信相比&#xff0c;多播可以极大地节省网络资源。 在因特网上进行的多播&#xff0c;称为 IP 多播。 1、单播 & 多播 如下所示&#xf…...

PIGOSS BSM监控国产数据库Oscar

前言神通数据库(原OSCAR数据库&#xff09;是天津神舟通用数据技术有限公司&#xff08;简称“神舟通用公司”&#xff09;拥有自主知识产权的企业级、大型通用关系型数据库管理系统。PIGOSS BSM作为网利友联科技完全自主研发的纯国产基础 IT 架构运行状态监测平台软件&#xf…...

Spring Boot中文件上传

Spring Boot中文件上传 前言 本篇主要参考Spring官方文档&#xff0c;整理了Spring Boot中文件上传如何实现&#xff0c;以及在代码中使用RestTemplate和HttpClient两种方式实现文件上传。 创建Spring Boot项目 首先创建一个Spring Boot Web项目&#xff0c;使用的Spring B…...

Github上传大文件(>25MB)教程

Github上传大文件&#xff08;>25MB&#xff09;教程Github上传大文件&#xff08;>25MB&#xff09;教程安装git安装Git Large File Storage实例踩坑点1&#xff1a;failed to push some refs to踩坑点2&#xff1a;main与master踩坑点3&#xff1a;Failed to connect t…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...