springboot下载文件例子

前言

目前网上遍布springmvc下载文件千篇一律,感觉像是互相抄来抄去,太糟糕了。
本文介绍springboot使用StreamingResponseBody下载文件,使用StreamingResponseBody下载文件使得服务器写和浏览器的读数据并行化。尤其在大文件下非常有效,速度很快。
我拿miui安装包来测试,文件大小超过1.5GB,JDK 1.8,springboot 2.2环境。

下载代码

首先熟悉一下Java的数据流,建议阅读这篇文章https://www.jianshu.com/p/63d1751d3eac,写的非常不错。此时我相信你已经熟练阅读完这篇文章,并且理解了Java数据流读写文件。

下载文件的开始需要定义下载文件的格式

response.setContentType("application/x-zip-compressed");
response.setHeader("Content-Disposition", "attachment; filename=\"chenrui-download.zip\"");

可以给这个文件起一个名字,filename那里就是起名字的地方。为了快速验证结果,filename的变量我写死了,当然在实际环境里,你可以根据需要填写变量进去。

根据文件路径读取文件

BufferedInputStream inputStream = 
new BufferedInputStream(new FileInputStream("D:\\miui_MI5_8.11.22_f9ead04910_8.0.zip"));

全部代码

@GetMapping("/download")
public StreamingResponseBody downlaodFile(HttpServletResponse response) throws FileNotFoundException {
    response.setContentType("application/x-zip-compressed");
    response.setHeader("Content-Disposition", "attachment; filename=\"chenrui-download.zip\"");
    BufferedInputStream inputStream = 
    new BufferedInputStream(new FileInputStream("D:\\miui_MI5_8.11.22_f9ead04910_8.0.zip"));
    return new StreamingResponseBody() {
        @Override
        public void writeTo(OutputStream outputStream) throws IOException {
            int nRead;
            long startTime = System.currentTimeMillis();

            byte[] bytes = new byte[1024];
            while ((nRead = inputStream.read(bytes, 0, bytes.length)) != -1) {
                outputStream.write(bytes, 0, nRead);
            }
            long userTime = System.currentTimeMillis() - startTime;

            System.out.println("使用时间" + userTime);
        }
    };
}
测试与验证

运行执行时间,单位毫秒
在这里插入图片描述
在下载的过程中,我截了一个图,速度达到了72.5MB每秒,效果还是很可观的。
在这里插入图片描述
在下载文件完成后需要对文件MD5验证是否一致;
windows下的命令如下。

certutil -hashfile filename MD5
certutil -hashfile filename SHA1
certutil -hashfile filename SHA256

在这里插入图片描述

希望指出文章错误

### 如何在Spring Boot应用中使用MinIO实现文件下载 #### 配置MinIO连接信息 为了使Spring Boot应用程序能够访问MinIO服务器,在`application.properties`或`application.yml`文件中需指定MinIO的相关参数设置[^3]: 对于`application.properties`: ```properties spring.minio.url=http://localhost:9000 spring.minio.accessKey=minio-access-key spring.minio.secretKey=minio-secret-key ``` 对于`application.yml`: ```yaml spring: minio: url: http://localhost:9000 accessKey: minio-access-key secretKey: minio-secret-key ``` #### 添加依赖项 确保项目的构建工具配置文件(如Maven的pom.xml或Gradle的build.gradle)已包含MinIO客户端库作为依赖。 对于Maven pom.xml: ```xml <dependency> <groupId>io.minio</groupId> <artifactId|minio|version>8.5.2</version> </dependency> ``` 对于Gradle build.gradle: ```groovy implementation 'io.minio:minio:8.5.2' ``` #### 编写业务逻辑代码 通过编写Java类来处理具体的文件下载操作。下面是一个简单的例子,展示了如何定义一个控制器用于响应HTTP请求并调用服务层的方法完成实际的文件读取工作。 创建一个新的Controller类 `FileDownloadController.java`: ```java import io.minio.MinioClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; @RestController public class FileDownloadController { private final MinioClient minioClient; public FileDownloadController(@Value("${spring.minio.url}") String endpoint, @Value("${spring.minio.accessKey}") String accessKey, @Value("${spring.minio.secretKey}") String secretKey) throws Exception { this.minioClient = new MinioClient(endpoint, accessKey, secretKey); } @GetMapping("/download/{bucketName}/{objectName}") public void downloadFile(@PathVariable String bucketName, @PathVariable String objectName, HttpServletResponse response) throws Exception { try (InputStream inputStream = minioClient.getObject(bucketName, objectName)) { response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=\"" + objectName + "\""); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { response.getOutputStream().write(buffer, 0, bytesRead); } response.flushBuffer(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } } ``` 这段代码实现了从特定存储桶内获取对象的功能,并将其流式传输给客户端浏览器以便于用户保存到本地磁盘上[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值