Spring Boot 3 文件上传、多文件上传、大文件分片上传、文件流处理以及批量操作

在 Spring Boot 3 中,可以通过内置的文件处理机制结合 Java 的 IO 流与多线程技术,实现文件上传、多文件上传、大文件分片上传、文件流处理以及批量操作的需求。以下是详细实现步骤:

1. 单文件上传

控制器代码

java 复制代码
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

@RestController
@RequestMapping("/file")
public class FileUploadController {

    private final String UPLOAD_DIR = "/path/to/upload/";

    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            File dest = new File(UPLOAD_DIR + file.getOriginalFilename());
            file.transferTo(dest); // 将上传的文件保存到目标位置
            return ResponseEntity.ok("File uploaded successfully: " + file.getOriginalFilename());
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.internalServerError().body("File upload failed");
        }
    }
}

2. 多文件上传

控制器代码

java 复制代码
@PostMapping("/upload-multiple")
public ResponseEntity<String> uploadMultipleFiles(@RequestParam("files") MultipartFile[] files) {
    StringBuilder message = new StringBuilder();
    for (MultipartFile file : files) {
        try {
            File dest = new File(UPLOAD_DIR + file.getOriginalFilename());
            file.transferTo(dest);
            message.append("Uploaded: ").append(file.getOriginalFilename()).append("\n");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.internalServerError().body("Failed to upload some files");
        }
    }
    return ResponseEntity.ok(message.toString());
}

3. 大文件分片上传

分片上传的核心在于将大文件拆分成小块上传,并在服务端进行合并。

分片上传控制器

java 复制代码
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

@RestController
@RequestMapping("/file")
public class ChunkUploadController {

    private final String UPLOAD_DIR = "/path/to/upload/";

    @PostMapping("/upload-chunk")
    public ResponseEntity<String> uploadChunk(
            @RequestParam("file") MultipartFile file,
            @RequestParam("chunkNumber") int chunkNumber,
            @RequestParam("totalChunks") int totalChunks,
            @RequestParam("filename") String filename) {

        try {
            File chunkFile = new File(UPLOAD_DIR + filename + ".part" + chunkNumber);
            file.transferTo(chunkFile);

            // 如果所有分片都已上传完毕,则进行合并
            if (isAllChunksUploaded(filename, totalChunks)) {
                mergeChunks(filename, totalChunks);
            }

            return ResponseEntity.ok("Chunk " + chunkNumber + " uploaded successfully");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.internalServerError().body("Failed to upload chunk");
        }
    }

    private boolean isAllChunksUploaded(String filename, int totalChunks) {
        for (int i = 1; i <= totalChunks; i++) {
            if (!Files.exists(Paths.get(UPLOAD_DIR + filename + ".part" + i))) {
                return false;
            }
        }
        return true;
    }

    private void mergeChunks(String filename, int totalChunks) throws IOException {
        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(UPLOAD_DIR + filename))) {
            for (int i = 1; i <= totalChunks; i++) {
                File chunkFile = new File(UPLOAD_DIR + filename + ".part" + i);
                Files.copy(chunkFile.toPath(), bos);
                chunkFile.delete(); // 合并后删除分片文件
            }
        }
    }
}

4. 文件流处理

文件流处理对于大文件来说可以减少内存占用,直接使用流式写入。

java 复制代码
@PostMapping("/upload-stream")
public ResponseEntity<String> uploadFileStream(@RequestParam("file") MultipartFile file) {
    try (InputStream inputStream = file.getInputStream();
         OutputStream outputStream = new FileOutputStream(UPLOAD_DIR + file.getOriginalFilename())) {

        byte[] buffer = new byte[1024 * 1024]; // 1MB 缓冲区
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }

        return ResponseEntity.ok("File uploaded successfully with streaming");
    } catch (IOException e) {
        e.printStackTrace();
        return ResponseEntity.internalServerError().body("File upload failed");
    }
}

5. 批量文件操作

示例:批量删除文件

java 复制代码
@DeleteMapping("/delete-multiple")
public ResponseEntity<String> deleteMultipleFiles(@RequestParam List<String> filenames) {
    StringBuilder message = new StringBuilder();
    for (String filename : filenames) {
        File file = new File(UPLOAD_DIR + filename);
        if (file.exists() && file.delete()) {
            message.append("Deleted: ").append(filename).append("\n");
        } else {
            message.append("Failed to delete: ").append(filename).append("\n");
        }
    }
    return ResponseEntity.ok(message.toString());
}

6. 分片技术的前端配合

前端分片上传示例(React)

js 复制代码
function uploadFileInChunks(file) {
    const chunkSize = 2 * 1024 * 1024; // 每片 2MB
    const totalChunks = Math.ceil(file.size / chunkSize);
    let chunkNumber = 0;

    async function uploadChunk() {
        const start = chunkNumber * chunkSize;
        const end = Math.min(start + chunkSize, file.size);
        const chunk = file.slice(start, end);

        const formData = new FormData();
        formData.append("file", chunk);
        formData.append("chunkNumber", chunkNumber + 1);
        formData.append("totalChunks", totalChunks);
        formData.append("filename", file.name);

        await fetch("/file/upload-chunk", {
            method: "POST",
            body: formData,
        });

        chunkNumber++;
        if (chunkNumber < totalChunks) {
            uploadChunk();
        } else {
            console.log("Upload complete");
        }
    }

    uploadChunk();
}

总结

单文件上传:适用于小文件。

多文件上传:批量处理多个文件。

大文件分片上传:解决超大文件的上传需求,并支持断点续传。

文件流处理:高效处理大文件,降低内存占用。

批量操作:如批量删除、下载。

分片技术:结合前端分片,支持更高效的文件上传和管理。

可以根据具体业务需求选择合适的技术方案。

相关推荐
程序猿乐锅4 分钟前
万字详解Single-flight(单飞模式)
java·开发语言·分布式·后端·学习·single-flight
Java后端的Ai之路16 分钟前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
AntsData1 小时前
用 12K+ 条亚马逊评论信号,定位机械键盘下一版该改什么
java·大数据·计算机外设
code2cat1 小时前
【随笔】连续批处理:长短请求怎样在迭代之间补位
java·人工智能·后端·大语言模型·vllm
最强小杰1 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
Flynn Liang1 小时前
Spring AI 2.0 深度解析:ChatClient、Advisor 链与 MCP——Java 工程师的 AI 落地最优解
java·人工智能·spring·大模型·架构设计·spring ai
灿飞1 小时前
Kotlin与Java虚拟机六:基础与类型系统:一切皆对象,但对象有代价
java·kotlin
计算机毕设定制辅导-无忧学长1 小时前
《基于微信小程序健康习惯激励系统设计与实现》
java·spring boot·mysql·微信小程序·uniapp·健康习惯激励系统
掘金者阿豪2 小时前
SQL Server数据迁移完成后,凌晨的数据库告警该怎么查?
前端·后端
鶴哥只手遮天2 小时前
AFSIM 2.9.0 深度解析·进阶卷第 1 章 插件源码精读:16 个 WSF 插件的架构与实现
后端