1.接口文件编写
@CrossOrigin(origins = "*")
@RestController
public class DemoController {
@PostMapping("file/upload")
public void upload(
Long size, Long totalSize,
Integer chunk, Integer totalChunks,
String fileName, MultipartFile file) throws IOException {
String path = System.getProperty("user.dir") + "\\service-01\\src\\main\\resources\\upload\\";
String filePath = path + fileName;
FileUtils.writeChunk(chunk, totalChunks, size, totalSize, filePath, file.getInputStream());
}
}
2.大文件上传工具类实现
public class FileUtils {
private static final Map<String, ChunkRemark> filesBuffer = new HashMap<>();
@Data
private static class ChunkRemark {
private int n;
private boolean[] mark;
public ChunkRemark(int n) {
this.n = n;
mark = new boolean[n];
}
public void mark(int chunk) {
mark[chunk] = true;
}
public boolean isLoaded() {
for (int i = 0; i < n; i++) {
if (!mark[i]) {
return false;
}
}
return true;
}
}
public static boolean isExists(String md5) {
return filesBuffer.get(md5) != null;
}
public static void writeChunk(int chunk, int totalChunk, long size, long totalSize, String md5, InputStream is) {
if (!isExists(md5)) {
filesBuffer.put(md5, new ChunkRemark(totalChunk));
}
try (RandomAccessFile fp = new RandomAccessFile(md5, "rw");) {
fp.setLength(totalSize);
fp.seek((chunk - 1) * size);
int len = 0;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1) {
fp.write(buf, 0, len);
buf = new byte[1024];
}
synchronized (FileUtils.class) {
filesBuffer.get(md5).mark(chunk - 1);
if (filesBuffer.get(md5).isLoaded()) {
System.out.println("file collected!");
filesBuffer.remove(md5);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.前端页面编写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
</head>
<body>
<form action="http://localhost:9002/file/upload" method="post" enctype="multipart/form-data">
<input type="file" id="file" name="file"/>
</form>
<script>
$(function () {
function fileSlice(file, piece = 1024) {
let total = file.size;
let start = 0;
let end = start + piece;
let chunks = [];
while (start < total) {
chunks.push(file.slice(start, end));
start = end;
end = start + piece;
}
return chunks;
}
$("#file").on("change", function (e) {
let file = e.target.files[0];
let fileSize = file.size;
let chunks = fileSlice(file);
console.log(chunks.length)
chunks.forEach((chunk, index) => {
let formData = new FormData();
formData.append("file", chunk);
formData.append("totalSize", fileSize);
formData.append("size", 1024);
formData.append("chunk", index + 1);
formData.append("totalChunks", chunks.length);
formData.append("fileName", file.name);
$.ajax({
url: "http://localhost:9002/file/upload",
type: "post",
contentType: false,
processData: false,
data: formData,
})
});
});
});
</script>
</body>
</html>