欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > Spring Boot 3 文件下载、多文件下载以及大文件分片下载、文件流处理、批量操作 和 分片技术

Spring Boot 3 文件下载、多文件下载以及大文件分片下载、文件流处理、批量操作 和 分片技术

2025/11/8 6:40:37 来源:https://blog.csdn.net/WithCYwind/article/details/144843444  浏览:    关键词:Spring Boot 3 文件下载、多文件下载以及大文件分片下载、文件流处理、批量操作 和 分片技术

在 Spring Boot 3 中,实现文件下载、多文件下载以及大文件分片下载需要结合以下功能:文件流处理、批量操作 和 分片技术。以下是详细实现方案:

1. 单文件下载

基础的单文件下载实现,可以参考以下代码:

@GetMapping("/download")
public ResponseEntity<Resource> downloadFile(@RequestParam String filename) {try {Path filePath = Paths.get("/path/to/files").resolve(filename).normalize();Resource resource = new UrlResource(filePath.toUri());if (!resource.exists()) {return ResponseEntity.notFound().build();}return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"").body(resource);} catch (MalformedURLException e) {return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();}
}

2. 多文件打包下载

对于多文件下载,可以通过将文件打包为 ZIP 文件,再进行下载。

控制器代码

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;@RestController
public class MultiFileDownloadController {private final String FILE_DIRECTORY = "/path/to/files";@GetMapping("/download-multiple")public ResponseEntity<byte[]> downloadMultipleFiles(@RequestParam List<String> filenames) {try (ByteArrayOutputStream baos = new ByteArrayOutputStream();ZipOutputStream zos = new ZipOutputStream(baos)) {for (String filename : filenames) {Path filePath = Paths.get(FILE_DIRECTORY).resolve(filename).normalize();if (Files.exists(filePath)) {zos.putNextEntry(new ZipEntry(filename));Files.copy(filePath, zos);zos.closeEntry();}}zos.finish();HttpHeaders headers = new HttpHeaders();headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"files.zip\"");return ResponseEntity.ok().headers(headers).body(baos.toByteArray());} catch (IOException e) {return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();}}
}

前端测试请求
使用 fetch 或 axios,发送文件名列表参数,接收 ZIP 文件。

3. 大文件分片下载

对于大文件分片下载,结合 HTTP Range 请求 来实现。

控制器代码

@GetMapping("/download-chunk")
public ResponseEntity<Resource> downloadFileInChunks(@RequestParam String filename,@RequestHeader(value = "Range", required = false) String rangeHeader) {try {Path filePath = Paths.get("/path/to/files").resolve(filename).normalize();Resource resource = new UrlResource(filePath.toUri());if (!resource.exists()) {return ResponseEntity.notFound().build();}long fileSize = Files.size(filePath);long rangeStart = 0, rangeEnd = fileSize - 1;if (rangeHeader != null && rangeHeader.startsWith("bytes=")) {String[] ranges = rangeHeader.replace("bytes=", "").split("-");rangeStart = Long.parseLong(ranges[0]);if (ranges.length > 1) {rangeEnd = Long.parseLong(ranges[1]);}}if (rangeStart > rangeEnd || rangeEnd >= fileSize) {return ResponseEntity.status(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE).build();}long chunkSize = rangeEnd - rangeStart + 1;InputStream inputStream = Files.newInputStream(filePath);inputStream.skip(rangeStart);HttpHeaders headers = new HttpHeaders();headers.add(HttpHeaders.CONTENT_RANGE, "bytes " + rangeStart + "-" + rangeEnd + "/" + fileSize);headers.add(HttpHeaders.ACCEPT_RANGES, "bytes");return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT).headers(headers).contentLength(chunkSize).body(new InputStreamResource(inputStream));} catch (IOException e) {return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();}
}

说明

Range 请求:

客户端通过设置 Range: bytes=start-end 来请求文件的部分内容。
响应头包含 Content-Range 和 Accept-Ranges,支持分片下载。

HTTP 状态码:

206 Partial Content:表示成功返回部分内容。
416 Requested Range Not Satisfiable:请求范围无效。

文件流处理:

使用 InputStream.skip() 跳过已读取部分。
确保响应的 Content-Length 与分片大小匹配。

4. 结合前端

分片下载示例(React)

function downloadLargeFile(filename) {const chunkSize = 1024 * 1024; // 每片1MBlet start = 0;function fetchChunk() {fetch(`/download-chunk?filename=${filename}`, {headers: {Range: `bytes=${start}-${start + chunkSize - 1}`}}).then(response => {if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}return response.blob();}).then(blob => {saveAs(blob, filename); // 使用 FileSaver.js 保存start += chunkSize;if (blob.size === chunkSize) {fetchChunk(); // 继续下载下一片}}).catch(err => console.error(err));}fetchChunk();
}

5. 总结

单文件下载:简单场景适用。
多文件下载:打包为 ZIP 文件传输,适合批量文件场景。
大文件分片下载:支持断点续传,提升用户体验,尤其适合视频流或超大文件传输。
根据具体业务需求,选择合适的实现方案。如果需要更多优化,比如 CDN 加速或并行分片,可以在此基础上扩展实现。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词