对于大文件的上传,客户端可以多线程分片上传,加快速率,服务端需要merge分片并存储。
常见思路:
通过status预上传接口获取一个key,再调用分片接口上传每一个分片,上传完调用publish接口完成上传。status接口的key用于串联整个过程。
一个简单的示例:
@RestController
@RequestMapping("/rest/n/testApi")
public class UploadController {
private ArrayListMultimap<String, byte[]> partsCache = ArrayListMultimap.create();
@Value("${upload.path}")
private String uploadPath;
@RequestMapping("/status")
public Object status() {
return fileKey();
}
@RequestMapping("/part")
public Object part(@RequestParam String fileKey,
@RequestParam int index,
@RequestParam MultipartFile data) throws IOException {
partsCache.get(fileKey).add(index, data.getBytes());
return "ok";
}
@RequestMapping("/upload")
public Object upload(@RequestParam String fileKey, @RequestParam String fileName) throws IOException {
try(ByteArrayOutputStream out = new ByteArrayOutputStream()) {
partsCache.get(fileKey).forEach(part -> {
try {
out.write(part);
} catch (IOException e) {
e.printStackTrace();
}
});
Path realPath = Paths.get(uploadPath + '/' + fileName);
if (!Files.exists(realPath)) {
Files.createDirectories(realPath.getParent());
Files.createFile(realPath);
}
Files.write(realPath, out.toByteArray());
}
return "ok";
}
}
public class FileUploadUtil {
public static String fileKey() {
return "" + System.currentTimeMillis();
}
}