fdfs上传代码优化
This commit is contained in:
parent
e1abac566c
commit
48cdbb8e0f
@ -10,17 +10,16 @@ import com.qiwenshare.common.util.PathUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
public class FastDFSUploader extends Uploader {
|
||||
public static Object lock = new Object();
|
||||
AppendFileStorageClient defaultAppendFileStorageClient;
|
||||
|
||||
UploadFile uploadFile;
|
||||
@ -28,16 +27,12 @@ public class FastDFSUploader extends Uploader {
|
||||
private static Map<String, Integer> CURRENT_UPLOAD_CHUNK_NUMBER = new HashMap<>();
|
||||
private static Map<String, Long> UPLOADED_SIZE = new HashMap<>();
|
||||
private static Map<String, String> STORE_PATH = new HashMap<>();
|
||||
private static Map<String, Boolean> LOCK_MAP = new HashMap<>();
|
||||
private static Map<String, Object> LOCK_MAP = new HashMap<>();
|
||||
|
||||
public FastDFSUploader() {
|
||||
|
||||
}
|
||||
|
||||
public FastDFSUploader(UploadFile uploadFile) {
|
||||
this.uploadFile = uploadFile;
|
||||
}
|
||||
|
||||
public FastDFSUploader(UploadFile uploadFile, AppendFileStorageClient defaultAppendFileStorageClient) {
|
||||
this.uploadFile = uploadFile;
|
||||
this.defaultAppendFileStorageClient = defaultAppendFileStorageClient;
|
||||
@ -76,13 +71,17 @@ public class FastDFSUploader extends Uploader {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private List<UploadFile> doUpload(String savePath, Iterator<String> iter){
|
||||
private List<UploadFile> doUpload(String savePath, Iterator<String> iter) {
|
||||
|
||||
List<UploadFile> saveUploadFileList = new ArrayList<>();
|
||||
|
||||
try {
|
||||
MultipartFile multipartfile = this.request.getFile(iter.next());
|
||||
synchronized (lock) {
|
||||
if (LOCK_MAP.get(uploadFile.getIdentifier()) == null) {
|
||||
LOCK_MAP.put(uploadFile.getIdentifier(), new Object());
|
||||
}
|
||||
}
|
||||
uploadFileChunk(multipartfile);
|
||||
|
||||
String timeStampName = getTimeStampName();
|
||||
@ -100,11 +99,10 @@ public class FastDFSUploader extends Uploader {
|
||||
File confFile = new File(PathUtil.getStaticPath() + FILE_SEPARATOR + confFilePath);
|
||||
|
||||
|
||||
|
||||
boolean isComplete = checkUploadStatus(uploadFile, confFile);
|
||||
if (isComplete) {
|
||||
log.info("分片上传完成");
|
||||
|
||||
LOCK_MAP.remove(uploadFile.getIdentifier());
|
||||
uploadFile.setUrl(STORE_PATH.get(uploadFile.getIdentifier()));
|
||||
uploadFile.setSuccess(1);
|
||||
uploadFile.setMessage("上传成功");
|
||||
@ -126,40 +124,23 @@ public class FastDFSUploader extends Uploader {
|
||||
|
||||
public void uploadFileChunk(MultipartFile multipartFile) {
|
||||
|
||||
// 存储在fastdfs不带组的路径
|
||||
// String noGroupPath = "";
|
||||
log.info("当前文件的Md5:{}", uploadFile.getIdentifier());
|
||||
synchronized (LOCK_MAP.get(uploadFile.getIdentifier())) {
|
||||
// 存储在fastdfs不带组的路径
|
||||
|
||||
// 真正的拥有者
|
||||
boolean currOwner = false;
|
||||
|
||||
try {
|
||||
|
||||
Boolean lock = LOCK_MAP.get(uploadFile.getIdentifier());
|
||||
if (lock != null && lock) {
|
||||
throw new UploadGeneralException("请求块锁失败");
|
||||
}
|
||||
LOCK_MAP.put(uploadFile.getIdentifier(), true);
|
||||
// 写入锁的当前拥有者
|
||||
currOwner = true;
|
||||
|
||||
// redis中记录当前应该传第几块(从0开始)
|
||||
Integer currentChunkInRedis = CURRENT_UPLOAD_CHUNK_NUMBER.get(uploadFile.getIdentifier());
|
||||
log.info("当前文件的Md5:{}", uploadFile.getIdentifier());
|
||||
|
||||
log.info("当前块的大小:{}", uploadFile.getCurrentChunkSize());
|
||||
if (currentChunkInRedis == null) {
|
||||
currentChunkInRedis = 1;
|
||||
if (CURRENT_UPLOAD_CHUNK_NUMBER.get(uploadFile.getIdentifier()) == null) {
|
||||
CURRENT_UPLOAD_CHUNK_NUMBER.put(uploadFile.getIdentifier(), 1);
|
||||
}
|
||||
|
||||
//此段代码保证顺序,如果满足条件则返回失败
|
||||
if (uploadFile.getChunkNumber() < currentChunkInRedis) {
|
||||
log.info("当前文件块已上传");
|
||||
throw new UploadGeneralException("当前文件块已上传");
|
||||
// return false;
|
||||
} else if (uploadFile.getChunkNumber() > currentChunkInRedis) {
|
||||
log.info("当前文件块需要等待上传,稍后请重试");
|
||||
throw new UploadGeneralException("当前文件块需要等待上传,稍后请重试");
|
||||
// return false;
|
||||
while (uploadFile.getChunkNumber() != CURRENT_UPLOAD_CHUNK_NUMBER.get(uploadFile.getIdentifier())) {
|
||||
try {
|
||||
LOCK_MAP.get(uploadFile.getIdentifier()).wait();
|
||||
} catch (InterruptedException e) {
|
||||
log.error("--------InterruptedException-------");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
log.info("***********开始上传第{}块**********", uploadFile.getChunkNumber());
|
||||
@ -180,13 +161,11 @@ public class FastDFSUploader extends Uploader {
|
||||
CURRENT_UPLOAD_CHUNK_NUMBER.put(uploadFile.getIdentifier(), uploadFile.getChunkNumber());
|
||||
log.info("获取远程文件路径出错");
|
||||
throw new UploadGeneralException("获取远程文件路径出错");
|
||||
// return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CURRENT_UPLOAD_CHUNK_NUMBER.put(uploadFile.getIdentifier(), uploadFile.getChunkNumber());
|
||||
log.error("初次上传远程文件出错", e);
|
||||
throw new UploadGeneralException("初次上传远程文件出错", e);
|
||||
// return false;
|
||||
}
|
||||
|
||||
STORE_PATH.put(uploadFile.getIdentifier(), storePath.getPath());
|
||||
@ -199,7 +178,6 @@ public class FastDFSUploader extends Uploader {
|
||||
log.error("无法获取已上传服务器文件地址");
|
||||
CURRENT_UPLOAD_CHUNK_NUMBER.put(uploadFile.getIdentifier(), uploadFile.getChunkNumber());
|
||||
throw new UploadGeneralException("无法获取已上传服务器文件地址");
|
||||
// return false;
|
||||
}
|
||||
try {
|
||||
Long alreadySize = UPLOADED_SIZE.get(uploadFile.getIdentifier());
|
||||
@ -213,20 +191,16 @@ public class FastDFSUploader extends Uploader {
|
||||
CURRENT_UPLOAD_CHUNK_NUMBER.put(uploadFile.getIdentifier(), uploadFile.getChunkNumber());
|
||||
log.error("更新远程文件出错", e);
|
||||
throw new UploadGeneralException("更新远程文件出错", e);
|
||||
// return false;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("上传文件错误", e);
|
||||
throw new UploadGeneralException("上传文件错误", e);
|
||||
// return false;
|
||||
}
|
||||
} finally {
|
||||
// 锁的当前拥有者才能释放块上传锁
|
||||
if (currOwner) {
|
||||
LOCK_MAP.put(uploadFile.getIdentifier(), false);
|
||||
}
|
||||
|
||||
log.info("***********第{}块上传成功**********", uploadFile.getChunkNumber());
|
||||
|
||||
LOCK_MAP.get(uploadFile.getIdentifier()).notifyAll();
|
||||
}
|
||||
log.info("***********第{}块上传成功**********", uploadFile.getChunkNumber());
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ public class FiletransferController {
|
||||
@Operation(summary = "下载文件", description = "下载文件接口", tags = {"filetransfer"})
|
||||
@MyLog(operation = "下载文件", module = CURRENT_MODULE)
|
||||
@RequestMapping(value = "/downloadfile", method = RequestMethod.GET)
|
||||
public String downloadFile(HttpServletResponse response, DownloadFileDTO downloadFileDTO) {
|
||||
public void downloadFile(HttpServletResponse response, DownloadFileDTO downloadFileDTO) {
|
||||
UserFile userFile = userFileService.getById(downloadFileDTO.getUserFileId());
|
||||
|
||||
String fileName = userFile.getFileName() + "." + userFile.getExtendName();
|
||||
@ -148,23 +148,36 @@ public class FiletransferController {
|
||||
response.setContentType("application/force-download");// 设置强制下载不打开
|
||||
response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
|
||||
byte[] buffer = new byte[1024];
|
||||
BufferedInputStream bis = null;
|
||||
|
||||
FileBean fileBean = fileService.getById(userFile.getFileId());
|
||||
if (fileBean.getIsOSS() != null && fileBean.getIsOSS() == 1) {
|
||||
aliyunDownload(response, buffer, fileBean);
|
||||
} else {
|
||||
localFileDownload(response, buffer, fileBean);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void localFileDownload(HttpServletResponse response, byte[] buffer, FileBean fileBean) {
|
||||
BufferedInputStream bis = null;
|
||||
//设置文件路径
|
||||
File file = FileOperation.newFile(PathUtil.getStaticPath() + fileBean.getFileUrl());
|
||||
if (file.exists()) {
|
||||
|
||||
|
||||
FileInputStream fis = null;
|
||||
|
||||
AliyunOSSDownload aliyunOSSDownload= new AliyunOSSDownload();
|
||||
OSS ossClient = aliyunOSSDownload.createOSSClient(qiwenFileConfig.getAliyun().getOss());
|
||||
OSSObject ossObject = ossClient.getObject(qiwenFileConfig.getAliyun().getOss().getBucketName(), fileBean.getTimeStampName());
|
||||
InputStream inputStream = ossObject.getObjectContent();
|
||||
try {
|
||||
bis = new BufferedInputStream(inputStream);
|
||||
fis = new FileInputStream(file);
|
||||
bis = new BufferedInputStream(fis);
|
||||
OutputStream os = response.getOutputStream();
|
||||
int i = bis.read(buffer);
|
||||
while (i != -1) {
|
||||
os.write(buffer, 0, i);
|
||||
i = bis.read(buffer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (bis != null) {
|
||||
@ -174,43 +187,37 @@ public class FiletransferController {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ossClient.shutdown();
|
||||
} else {
|
||||
//设置文件路径
|
||||
File file = FileOperation.newFile(PathUtil.getStaticPath() + fileBean.getFileUrl());
|
||||
if (file.exists()) {
|
||||
|
||||
|
||||
FileInputStream fis = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void aliyunDownload(HttpServletResponse response, byte[] buffer, FileBean fileBean) {
|
||||
BufferedInputStream bis = null;
|
||||
AliyunOSSDownload aliyunOSSDownload= new AliyunOSSDownload();
|
||||
OSS ossClient = aliyunOSSDownload.createOSSClient(qiwenFileConfig.getAliyun().getOss());
|
||||
OSSObject ossObject = ossClient.getObject(qiwenFileConfig.getAliyun().getOss().getBucketName(), fileBean.getTimeStampName());
|
||||
InputStream inputStream = ossObject.getObjectContent();
|
||||
try {
|
||||
bis = new BufferedInputStream(inputStream);
|
||||
OutputStream os = response.getOutputStream();
|
||||
int i = bis.read(buffer);
|
||||
while (i != -1) {
|
||||
os.write(buffer, 0, i);
|
||||
i = bis.read(buffer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (bis != null) {
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
bis = new BufferedInputStream(fis);
|
||||
OutputStream os = response.getOutputStream();
|
||||
int i = bis.read(buffer);
|
||||
while (i != -1) {
|
||||
os.write(buffer, 0, i);
|
||||
i = bis.read(buffer);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
bis.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (bis != null) {
|
||||
try {
|
||||
bis.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
|
||||
ossClient.shutdown();
|
||||
}
|
||||
|
||||
@Operation(summary = "获取存储信息", description = "获取存储信息", tags = {"filetransfer"})
|
||||
|
Loading…
Reference in New Issue
Block a user