切片上传,和断点续传的概念 大家自己百度 话不多说直接上代码
1.初始话断点续传
@Autowired
private RedisTemplate<String,Object> redisTemplate;
private Lock lock = new ReentrantLock();
@ApiOperation(value = "开启分片上传")
@GetMapping("/initiateMultipartUpload/{filename}")
@GlobalApiResponses
public Response initiateMultipartUpload(@PathVariable String filename,@PathVariable String total){
HashMap<String, Object> map = new HashMap<>();
// Object[] objects = Arrays.stream(new String[total]).map(s -> UUID.randomUUID().toString()).toArray();
// map.put("data",objects);
filename += System.currentTimeMills()+"可以拼上用户id,只要防止名称重复就好"+filename;
String fileId = UUIDUtil.getUUID(); //构建一个唯一的id 返回给前台 唯一标识
map.put("fileId",fileId);
map.put("filename",file
// RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
// redisTemplate.opsForValue().set(UUID.randomUUID().toString(),objects);
Object uploadFile = redisTemplate.opsForValue().get("uploadFile");
lock.lock();
try{
if (uploadFile==null) {
//用uploadFile 作为key 可以查出正在上传的分片
redisTemplate.opsForValue().set("uploadFile", fileId);
}else {
redisTemplate.opsForValue().set("uploadFile",uploadFile.toString()+","+fileId);
}
redisTemplate.opsForValue().set(fileId,"");
}finally{
lock.unlock()
}
return Response.withData(map);
}
2.分片上传
@ApiOperation(value = "分片上传之每片上传")
@PostMapping("/uploadPart")
@GlobalApiResponses
public Response uploadPart(@RequestParam("file") MultipartFile multipartFile,FilePart filePart) throws IOException{
// if (amazonS3==null) {
// amazonS3 = GetConnection();
// }
String fileId = filePart.getFileId();
String filename = filePart.getName()+"."+filePart.getSuffix();
Object fileId1 = redisTemplate.opsForValue().get("uploadFile");
System.out.println(fileId1.toString());
System.out.println(redisTemplate.opsForValue().get(fileId)+"ssss ");
File directory = new File("D:\\temporary\\"+fileId);
if (directory.mkdirs()){
directory.mkdir();
}
File localFile = new File("D:\\temporary\\"+fileId+"\\"+filename);
multipartFile.transferTo(localFile);
lock.lock();
try {
if (redisTemplate.opsForValue().get(fileId) == null || redisTemplate.opsForValue().get(fileId).equals("")) {
redisTemplate.opsForValue().set(fileId, filename.substring(0, filename.indexOf(".")));
} else {
redisTemplate.opsForValue().set(fileId, redisTemplate.opsForValue().get(fileId).toString() + "," + filename.substring(0, filename.indexOf(".")));
}
}finally {
lock.unlock();
}
return Response.withData(redisTemplate.opsForValue().get(fileId));
}
3.合并上传
@ApiOperation(value = "合并分片")
@PostMapping("/merge")
@GlobalApiResponses
public Response merge(@RequestBody FilePart filePart) throws IOException {
String fileId = filePart.getFileId();
String name = filePart.getName();
String suffix = filePart.getSuffix();
FileOutputStream fileOutputStream = null;
FileInputStream fileInputStream = null;
byte[] byt = new byte[10*1024*1024];
String[] split = null;
while (true){
Object file = redisTemplate.opsForValue().get(fileId);
split = file.toString().split(",");
if (split.length!=Integer.valueOf(filePart.getTotal())){
continue;
}
File newFile = new File("D:\\temporary\\"+fileId+"\\"+name+"."+suffix);
fileOutputStream = new FileOutputStream(newFile, true);
break;
}
int len ;
for (int i = 0; i < split.length; i++) {
fileInputStream = new FileInputStream(new File("D:\\temporary\\"+fileId+"\\"+i+"."+suffix));
while((len=fileInputStream.read(byt))!=-1){
fileOutputStream.write(byt,0,len);
}
fileInputStream.close();
}
fileOutputStream.close();
log.info("合并分片结束,开始删除分片");
File parentFile = null;
for (int i = 0; i < split.length; i++) {
File file1 = new File("D:\\temporary\\"+fileId+"\\"+i+"."+suffix);
parentFile = file1.getParentFile();
boolean delete = file1.delete();
if (!delete){
log.info("D:\\temporary\\"+fileId+"\\"+i+"."+suffix+" 删除失败");
throw new BusinessException("删除失败");
}
}
boolean delete1 = parentFile.delete();
if (!delete1){
log.info("D:\\temporary\\"+fileId+ "删除失败");
}
redisTemplate.delete(fileId);
String uploadFile = redisTemplate.opsForValue().get("uploadFile").toString();
Object[] objects = Arrays.stream(uploadFile.split(",")).filter(s -> !s.equals(fileId)).toArray();
redisTemplate.opsForValue().set("uploadFile",objects);
return Response.withData("合并结束");
}
4.查询正在上传的分片 以及失败重试后查询已经上传完成的分片
@ApiOperation(value = "查询redis")
@PostMapping("/getRedis")
@GlobalApiResponses
public Response getRedis(String key){
return Response.withData(redisTemplate.opsForValue().get(key));
}
@ApiOperation(value = "删除redis")
@PostMapping("/deleteRedis")
@GlobalApiResponses
public Response deleteRedis(String key){
return Response.withData(redisTemplate.delete(key));
}
5.下载上传成功的文件
@ApiOperation(value = "下载文件")
@GetMapping("/getFile/{fileId}/{fileName}")
@GlobalApiResponses
public Response getFile(@PathVariable String fileId, @PathVariable String fileName, HttpServletResponse response){
FileInputStream fis = null;
ServletOutputStream outputStream = null;
try {
File file = new File("D:\\temporary\\" + fileId + "\\" + fileName);
outputStream = response.getOutputStream();
response.setContentType("application/force-download");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
fis = new FileInputStream(file);
// IOUtils.copy(fis,outputStream);
byte[] bytes = new byte[1024 * 1024];
int len;
while ((len = fis.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
response.getOutputStream().flush();
}catch (IOException e){
throw new BusinessException("下载失败请联系管理员");
}finally {
try {
fis.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return Response.withData("");
}