package com.ard.inspection.service.impl;
|
|
import com.ard.inspection.service.IBigFileUploadService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
import org.springframework.web.multipart.MultipartFile;
|
|
import java.io.File;
|
import java.io.IOException;
|
import java.io.RandomAccessFile;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* @author xia
|
*/
|
@Service
|
@Slf4j
|
public class BigFileUploadServiceImpl implements IBigFileUploadService {
|
|
@Override
|
public Map<String, Object> checkChunk(String fileMd5,String chunkPath) {
|
Map<String, Object> result = new HashMap<>();
|
try {
|
File chunkFolder = new File(chunkPath + File.separator + fileMd5);
|
if (!chunkFolder.exists()) {
|
result.put("exception", "分片不存在!!!");
|
return result;
|
}
|
|
File[] chunks = chunkFolder.listFiles();
|
if (chunks == null || chunks.length == 0) {
|
result.put("exception", "无分片!!!");
|
return result;
|
}
|
|
List<Integer> uploadedChunks = Arrays.stream(chunks)
|
.map(file -> Integer.parseInt(file.getName().split("\\.")[0]))
|
.collect(Collectors.toList());
|
result.put("message", uploadedChunks);
|
return result;
|
} catch (Exception e) {
|
log.error("检查分片失败", e);
|
result.put("exception", "检查分片失败!!!");
|
return result;
|
}
|
}
|
|
@Override
|
public Map<String, Object> uploadChunk(MultipartFile file,
|
Integer chunkNumber,
|
String fileMd5,
|
String chunkPath) {
|
Map<String, Object> result = new HashMap<>();
|
try {
|
// 验证参数
|
if (file.isEmpty()) {
|
result.put("exception", "文件不能为空!!!");
|
return result;
|
}
|
|
// 创建分片目录
|
String chunkDirPath = chunkPath + File.separator + fileMd5;
|
File chunkDir = new File(chunkDirPath);
|
if (!chunkDir.exists()) {
|
chunkDir.mkdirs();
|
}
|
|
// 保存分片
|
String chunkFileName = chunkNumber + ".part";
|
File chunkFile = new File(chunkDir, chunkFileName);
|
file.transferTo(chunkFile);
|
|
result.put("message", "分片上传成功!!!");
|
return result;
|
} catch (IOException e) {
|
log.error("分片上传失败", e);
|
result.put("exception", "分片上传失败!!!");
|
return result;
|
}
|
}
|
|
@Override
|
public Map<String, Object> mergeChunks(String md5,String fileName,String uploadPath) {
|
Map<String, Object> result = new HashMap<>();
|
// 临时目录
|
String chunkDir = uploadPath + File.separator + md5;
|
File dir = new File(chunkDir);
|
if (!dir.exists()) {
|
result.put("exception", "切片目录不存在");
|
return result;
|
}
|
// 获取所有切片文件
|
File[] chunks = dir.listFiles();
|
if (chunks == null || chunks.length == 0) {
|
result.put("exception", "没有切片文件");
|
return result;
|
}
|
// 按照切片索引排序
|
Arrays.sort(chunks, (a, b) -> {
|
int aIndex = Integer.parseInt(a.getName().split("\\.")[0]);
|
int bIndex = Integer.parseInt(b.getName().split("\\.")[0]);
|
return aIndex - bIndex;
|
});
|
|
// 合并后的文件,这里使用原始文件名,为了避免重名,可以加上时间戳或使用UUID
|
// 这里根据业务需求,可以保存到数据库,记录文件路径等信息
|
String ext = fileName.substring(fileName.lastIndexOf("."));
|
String newFileName = UUID.randomUUID().toString().replace("-", "") + ext; // 生成新文件名
|
File mergeFile = new File(uploadPath, newFileName);
|
|
try (RandomAccessFile randomAccessFile = new RandomAccessFile(mergeFile, "rw")) {
|
byte[] buffer = new byte[1024 * 1024]; // 1MB缓冲区
|
for (File chunk : chunks) {
|
try (RandomAccessFile chunkFile = new RandomAccessFile(chunk, "r")) {
|
int len;
|
while ((len = chunkFile.read(buffer)) != -1) {
|
randomAccessFile.write(buffer, 0, len);
|
}
|
}
|
// 删除切片文件
|
chunk.delete();
|
}
|
// 删除临时目录
|
dir.delete();
|
} catch (IOException e) {
|
log.error("合并文件失败", e);
|
result.put("exception", "合并文件失败");
|
return result;
|
}
|
|
// 这里可以保存文件信息到数据库,例如文件路径、文件名、md5等
|
// fileService.saveFileInfo(...);
|
|
result.put("message", "文件合并成功");
|
return result;
|
}
|
|
}
|