springboot 、html分片上傳,斷點(diǎn)續(xù)傳
- 后端代碼
private String UPLOAD_URL = "F:/20230509/";
private String UPLOAD_SUFFIX_URL = "/gsl/www/";
public String getUPLOAD_URL() {
return UPLOAD_URL + UPLOAD_SUFFIX_URL;
}
@PostMapping("/o_upload")
public Result upload1(@RequestParam("file") MultipartFile multipartFile,
@RequestParam("fileName") String fileName,
@RequestParam("chunkNumber") int chunkNumber,
@RequestParam("totalChunks") int totalChunks) throws IOException {
UserDetail user = SecurityUser.getUser();
String originalFileName = StringUtils.cleanPath(multipartFile.getOriginalFilename());
String fileExtension = getFileExtension(originalFileName);
String uniqueFileName = fileName + "_" + chunkNumber + "." + fileExtension;
Path uploadPath = Paths.get(this.getUPLOAD_URL());
if (!Files.exists(uploadPath)) {
Files.createDirectories(uploadPath);
}
Path filePath = Paths.get(this.getUPLOAD_URL() + uniqueFileName);
Files.write(filePath, multipartFile.getBytes());
if (chunkNumber == totalChunks - 1) {
return mergeChunks(fileName, totalChunks, fileExtension, user.getId());
} else {
return new Result().error("上傳失敗");
}
}
private String getFileExtension(String fileName) {
int dotIndex = fileName.lastIndexOf(".");
if (dotIndex > 0) {
return fileName.substring(dotIndex + 1);
} else {
return "";
}
}
/**
* 合并分片
* @param fileName
* @param totalChunks
* @param fileExtension
* @param userId
* @return
* @throws IOException
*/
private Result mergeChunks(String fileName, int totalChunks, String fileExtension, Long userId) throws IOException {
Path mergedFilePath = Paths.get(this.getUPLOAD_URL() + fileName + "." + fileExtension);
if (!Files.exists(mergedFilePath)) {
Files.createFile(mergedFilePath);
}
for (int i = 0; i < totalChunks; i++) {
Path chunkFilePath = Paths.get(this.getUPLOAD_URL() + fileName + "_" + i + "." + fileExtension);
Files.write(mergedFilePath, Files.readAllBytes(chunkFilePath), StandardOpenOption.APPEND);
Files.delete(chunkFilePath);
}
Path filePath = Paths.get(this.getUPLOAD_URL() + fileName);
File file = new File(filePath.toString());
// 原文件名稱
String extension = file.getName().substring(0, file.getName().lastIndexOf("."));
// 后綴
String suffix = "." + file.getName().substring(file.getName().lastIndexOf(".") + 1);
// 新的文件名稱
String newFileName = System.currentTimeMillis() + suffix;
// 文件重命名
File renamedFile = new File(file.getParent(), newFileName);
file.renameTo(renamedFile);
// 文件路徑:/gsl/cms/1683616117391.zip
String resourceUrl = UPLOAD_SUFFIX_URL + newFileName;
// 可保存到數(shù)據(jù)庫
Map<String, Object> map = new HashMap<>();
map.put("url", resourceUrl);
return new Result().ok(map);
}
注意:合并分片代碼中:Files.write(mergedFilePath, Files.readAllBytes(chunkFilePath), StandardOpenOption.APPEND);
文章來源地址http://www.zghlxwxcb.cn/news/detail-445821.html
如果不設(shè)置該值StandardOpenOption.APPEND
,無法打開合并后的文件
- 前端代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>File Upload Test</title>
</head>
<body>
<input type="file" id="fileInput">
<button onclick="uploadFile()">Upload</button>
<script>
function uploadFile() {
const file = document.getElementById("fileInput").files[0];
const url = "/upload/o_upload";
const chunkSize = 1024 * 1024; // 每個(gè)塊的大?。ㄗ止?jié))
const fileSize = file.size; // 文件的總大小
const totalChunks = Math.ceil(fileSize / chunkSize); // 文件被分成的總塊數(shù)
let chunkNumber = 0; // 當(dāng)前上傳的塊的編號(hào)
let startByte = 0; // 當(dāng)前上傳塊的起始字節(jié)位置
let endByte = chunkSize; // 當(dāng)前上傳塊的結(jié)束字節(jié)位置(不包括)
uploadChunk();
function uploadChunk() {
const chunk = file.slice(startByte, endByte); // 獲取當(dāng)前上傳塊的內(nèi)容
const formData = new FormData(); // 創(chuàng)建FormData對(duì)象
// 將參數(shù)添加到FormData對(duì)象中
formData.append("file", chunk);
formData.append("chunkNumber", chunkNumber);
formData.append("totalChunks", totalChunks);
formData.append("fileName", file.name);
formData.append("fileSize", fileSize);
// 創(chuàng)建XMLHttpRequest對(duì)象
const xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
// 監(jiān)聽XMLHttpRequest對(duì)象的事件
xhr.onload = function() {
if (xhr.status === 200) {
// 上傳成功,繼續(xù)上傳下一塊
chunkNumber++;
startByte = endByte;
endByte = Math.min(startByte + chunkSize, fileSize);
if (startByte < fileSize) {
uploadChunk();
} else {
// 所有塊上傳成功
console.log("Upload completed");
}
} else {
// 上傳失敗,嘗試重傳當(dāng)前塊
console.error(xhr.statusText);
setTimeout(uploadChunk, 1000);
}
};
xhr.onerror = function() {
// 網(wǎng)絡(luò)錯(cuò)誤,嘗試重傳當(dāng)前塊
console.error(xhr.statusText);
setTimeout(uploadChunk, 1000);
};
// 發(fā)送POST請(qǐng)求
xhr.send(formData);
}
}
</script>
</body>
</html>
文章來源:http://www.zghlxwxcb.cn/news/detail-445821.html
到了這里,關(guān)于springboot 、html分片上傳,斷點(diǎn)續(xù)傳的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!