spring boot + vue 实现分片上传代码
时间: 2023-10-23 10:13:03 浏览: 141
很好,我能够为您提供您请求的信息。下面是使用spring boot和vue实现分片上传的代码示例:
后端代码:
```
//文件上传
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String upload(HttpServletRequest request) throws Exception {
//获取上传的文件
MultipartFile file = ((MultipartHttpServletRequest) request).getFile("file");
//获取保存文件的路径
String path = request.getSession().getServletContext().getRealPath("/uploads/");
//创建文件夹
File uploadDir = new File(path);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
//分片的序列号
String chunk = request.getParameter("chunk");
//分片上传的总数
String chunks = request.getParameter("chunks");
//分片文件的存储目录
String chunkPath = path + "/" + chunk;
File chunkDir = new File(chunkPath);
if (!chunkDir.exists()) {
chunkDir.mkdir();
}
//生成随机的文件名
String fileName = UUID.randomUUID().toString().replace("-", "") + "_" + file.getOriginalFilename();
//保存文件到分片目录
file.transferTo(new File(chunkPath + "/" + fileName));
//将当前分片的序列号和总数保存到redis
redisTemplate.opsForValue().set(file.getOriginalFilename() + "_chunk_" + chunk, chunks);
//如果这是最后一个分片,将所有分片合并成一个文件
if (Integer.parseInt(chunk) == Integer.parseInt(chunks) - 1) {
//创建新的文件
File newFile = new File(path + "/" + fileName);
//获取分片目录下的所有文件列表
File[] files = chunkDir.listFiles();
//通过文件名的长度排序,确保分片之后的顺序正确
Arrays.sort(files, Comparator.comparingInt((File f) -> f.getName().length()));
//将所有分片合并到新文件中
for (File f : files) {
FileOutputStream fos = new FileOutputStream(newFile, true);
FileInputStream fis = new FileInputStream(f);
byte[] bytes = new byte[1024];
int len = 0;
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
fis.close();
fos.close();
f.delete(); //删除已经合并的分片
}
//删除分片目录
chunkDir.delete();
//从redis中删除保存的分片信息
redisTemplate.delete(file.getOriginalFilename() + "_chunk_*");
}
return fileName;
}
```
前端代码:
```
<template>
<div>
<input type="file" @change="handleFileChange">
<button @click="handleUpload">上传</button>
</div>
</template>
<script>
export default {
data() {
return {
file: null
}
},
methods: {
handleFileChange(e) {
this.file = e.target.files[0];
},
handleUpload() {
let chunkSize = 1 * 1024 * 1024; //每个分片的大小为1MB
let fileSize = this.file.size;
let chunks = Math.ceil(fileSize / chunkSize); //需要上传的总分片数
let currentChunk = 0; //当前上传的分片序号
let fileReader = new FileReader(); //文件读取器
fileReader.onload = (e) => {
let blob = new Blob([e.target.result]); //将数据转换为二进制数据
let xhr = new XMLHttpRequest(); //创建AJAX向后端发送请求
xhr.open('POST', 'http://localhost:8080/upload', true);
xhr.setRequestHeader("Content-type", "multipart/form-data"); //设置请求头
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
}
let formData = new FormData(); //创建表单数据对象,用于向后端发送数据
formData.append("file", blob, this.file.name); //添加文件数据
formData.append("chunk", currentChunk); //添加当前分片的序号
formData.append("chunks", chunks); //添加分片的总数
xhr.send(formData); //发送请求
currentChunk++; //分片序号加1
if (currentChunk < chunks) { //如果还有分片需要上传,继续上传下一分片
loadNext();
}
}
let loadNext = () => {
let start = currentChunk * chunkSize;
let end = Math.min(start + chunkSize, fileSize);
fileReader.readAsArrayBuffer(this.file.slice(start, end)); //读取下一分片的数据
}
loadNext(); //开始上传第一分片
}
}
}
</script>
```
希望这段代码能够对您有所帮助!
阅读全文