Java如何实现文件分片上传的?

摘要:文件分片上传 核心思想:前端分片上传,后端合并文件 测试页面 <!doctype html> <html lang="en&quot
文件分片上传 核心思想:前端分片上传,后端合并文件 测试页面 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>文件分片上传</title> </head> <body> <input type="file" id="fileInput" /> <button onclick="uploadFile()">上传</button> <script> function uploadFile() { const fileInput = document.getElementById('fileInput') const file = fileInput.files[0] if (!file) { alert('请选择文件') return } const chunkSize = 1024 * 1024 // 每个分片 1MB const totalChunks = Math.ceil(file.size / chunkSize) const identifier = file.name + '_' + file.size let currentChunk = 0 function uploadChunk() { const start = currentChunk * 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', currentChunk) formData.append('totalChunks', totalChunks) formData.append('identifier', identifier) const xhr = new XMLHttpRequest() xhr.open('POST', 'http://localhost:8080/file/uploadChunk', true) xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { const response = JSON.parse(xhr.responseText) if (response.success) { currentChunk++ if (currentChunk < totalChunks) { uploadChunk() } else { mergeChunks() } } else { alert('分片上传失败: ' + response.message) } } else { alert('请求出错: ' + xhr.status) } } } xhr.send(formData) } function mergeChunks() { const xhr = new XMLHttpRequest() xhr.open('POST', 'http://localhost:8080/file/mergeChunks', true) xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { const response = JSON.parse(xhr.responseText) if (response.success) { alert('文件上传成功') } else { alert('文件合并失败: ' + response.message) } } else { alert('请求出错: ' + xhr.status) } } } const mergeData = new FormData() mergeData.append('identifier', identifier) mergeData.append('totalChunks', totalChunks) xhr.send(mergeData) } uploadChunk() } </script> </body> </html> 后端代码实现 private static final String TEMP_DIR = 定义临时目录; /** * 分片上传文件 * * @param file 文件 * @param chunkNumber 分片文件下标 * @param totalChunks 分片总数 * @param identifier 分片文件标识 * @return */ public Map<String, Object> uploadChunk(MultipartFile file, int chunkNumber, int totalChunks, String identifier) { Map<String, Object> result = new HashMap<>(); try { // 创建临时存储目录 File tempDir = new File(TEMP_DIR + identifier); if (!tempDir.exists()) { tempDir.mkdirs(); } // 保存分片文件 File chunkFile = new File(tempDir, "chunk_" + chunkNumber); try (InputStream inputStream = file.getInputStream(); FileOutputStream outputStream = new FileOutputStream(chunkFile)) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } } result.put("success", true); result.put("message", "分片上传成功"); } catch (IOException e) { result.put("success", false); result.put("message", "分片上传失败: " + e.getMessage()); } return result; } /** * 合并分片文件 * * @param identifier 分片文件标识 * @param totalChunks 分片总数 * @return */ public Map<String, Object> mergeChunks(String identifier, int totalChunks) { Map<String, Object> result = new HashMap<>(); try { File tempDir = new File(TEMP_DIR + identifier); if (tempDir.exists() && tempDir.isDirectory()) { File mergedFile = new File(TEMP_DIR + identifier.split("_")[0]); try (FileOutputStream outputStream = new FileOutputStream(mergedFile)) { for (int i = 0; i < totalChunks; i++) { File chunkFile = new File(tempDir, "chunk_" + i); if (chunkFile.exists()) { try (InputStream inputStream = java.nio.file.Files.newInputStream(chunkFile.toPath())) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } } // 删除分片文件 chunkFile.delete(); } } } // 删除临时目录 tempDir.delete(); result.put("success", true); result.put("message", "文件合并成功"); } else { result.put("success", false); result.put("message", "临时目录不存在"); } } catch (IOException e) { result.put("success", false); result.put("message", "文件合并失败: " + e.getMessage()); } return result; }