新增文件MD5校验,去除重复文件

This commit is contained in:
WenG 2020-11-18 21:31:52 +08:00
parent 966141e943
commit cb98c405f4
4 changed files with 154 additions and 10 deletions

View File

@ -32,6 +32,7 @@ public interface IFileDao {
/**
* 删除文件
*
* @param params
* @throws RemoveException
*/
@ -39,6 +40,7 @@ public interface IFileDao {
/**
* 删除文件(物理删除)
*
* @param params
* @throws RemoveException
*/
@ -73,9 +75,18 @@ public interface IFileDao {
/**
* 获取文件列表(带路径)
*
* @return
* @throws SearchException
*/
List<FileInfoWithPathDTO> listFileInfoWithPath(Map<String, Object> params) throws SearchException;
/**
* 文件列表
*
* @param fileMd5 文件MD5值
* @return
* @throws SearchException
*/
List<FileInfoDTO> listFileByMd5(String fileMd5) throws SearchException;
}

View File

@ -17,6 +17,8 @@ import io.swagger.annotations.ApiModelProperty;
@ApiModel
public class FileInfoDTO extends FileDTO {
@ApiModelProperty(name = "filePath", value = "文件全路径")
private String filePath;
@ApiModelProperty(name = "fileUrl", value = "文件链接")
private String fileUrl;
@ApiModelProperty(name = "fileSummary", value = "文件说明")
@ -24,6 +26,14 @@ public class FileInfoDTO extends FileDTO {
@ApiModelProperty(name = "isBack", value = "是否备份")
private Integer isBack;
public String getFilePath() {
return filePath == null ? "" : filePath.trim();
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
@Override
public String getFileUrl() {
return fileUrl == null ? "" : fileUrl.trim();
@ -53,7 +63,9 @@ public class FileInfoDTO extends FileDTO {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("\"fileUrl\":\"")
sb.append("\"filePath\":\"")
.append(filePath).append('\"');
sb.append(",\"fileUrl\":\"")
.append(fileUrl).append('\"');
sb.append(",\"fileSummary\":\"")
.append(fileSummary).append('\"');

View File

@ -42,6 +42,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.*;
/**
@ -55,6 +56,7 @@ import java.util.*;
public class FileServiceImpl extends AbstractService implements IFileService {
private static final Logger LOG = LoggerFactory.getLogger(FileServiceImpl.class);
private static final char[] HEX_CODE = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
@Autowired
private FileProperties fileProperties;
@ -153,9 +155,26 @@ public class FileServiceImpl extends AbstractService implements IFileService {
String uploadPath = getUploadPath(baseUploadPath, uploadTypeEnum, fileType);
// 文件保存名称
String uploadFileName = getUploadFileName(fileType);
if (!uploadFile(uploadFile, uploadPath, uploadFileName)) {
String fileMd5 = uploadFile(uploadFile, uploadPath, uploadFileName);
if (fileMd5 == null) {
throw new SaveException("文件上传失败");
}
// 获取MD5相同的文件
List<FileInfoDTO> fileInfoDTOs = fileDao.listFileByMd5("MD5:" + fileMd5);
if (fileInfoDTOs.size() > 0) {
// 删除新增的文件
File uploadedFile = new File(uploadPath + File.separator + uploadFileName);
if (uploadedFile.exists()) {
uploadedFile.delete();
}
// 保存记录但文件信息都是原有的文件
params.clear();
FileInfoDTO fileInfoDTO = fileInfoDTOs.get(0);
params.put("fileSummary", "REF:" + fileInfoDTO.getFileId());
saveFile(token, params, fileInfoDTO.getFileName(), fileInfoDTO.getFilePath(), fileInfoDTO.getFileUrl(), fileInfoDTO.getFileType(), fileInfoDTO.getFileSize());
return;
}
params.put("fileSummary", "MD5:" + fileMd5);
saveUploadFileInfo(token, fileName, uploadPath, uploadFileName, fileType, fileSize, params);
}
@ -205,10 +224,25 @@ public class FileServiceImpl extends AbstractService implements IFileService {
File photo = new File(fileFullPath);
fileSize = photo.length();
}
saveFile(token, params, fileName, fileFullPath, String.format("files/%s/%s", fixPath, uploadFileName), fileType, fileSize);
}
/**
* 保存文件
*
* @param token token
* @param params 参数
* @param fileName 文件名
* @param fileFullPath 文件全路径
* @param fileUrl 文件相对地址
* @param fileType 文件类型
* @param fileSize 文件大小
*/
private void saveFile(String token, Map<String, Object> params, String fileName, String fileFullPath, String fileUrl, String fileType, long fileSize) {
params.put("fileId", UUIDUtil.getUUID());
params.put("fileName", fileName);
params.put("filePath", fileFullPath);
params.put("fileUrl", String.format("files/%s/%s", fixPath, uploadFileName));
params.put("fileUrl", fileUrl);
params.put("fileType", fileType);
params.put("fileSize", fileSize);
params.put("isBack", 0);
@ -596,7 +630,8 @@ public class FileServiceImpl extends AbstractService implements IFileService {
* @param uploadFileName
* @return
*/
private boolean uploadFile(MultipartFile uploadFile, String filePath, String uploadFileName) throws FileException {
private String uploadFile(MultipartFile uploadFile, String filePath, String uploadFileName) throws FileException {
String fileMd5;
File uploadFolder = new File(filePath);
if (!uploadFolder.exists()) {
uploadFolder.mkdirs();
@ -606,10 +641,20 @@ public class FileServiceImpl extends AbstractService implements IFileService {
try {
uploadFileInputStream = uploadFile.getInputStream();
uploadFileOutputStream = new FileOutputStream(new File(uploadFolder + "/" + uploadFileName));
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
for (byte[] buf = new byte[INPUT_STREAM_SIZE]; uploadFileInputStream.read(buf) > -1; ) {
uploadFileOutputStream.write(buf, 0, buf.length);
messageDigest.update(buf, 0, buf.length);
}
uploadFileOutputStream.flush();
// 计算文件的MD5
byte[] data = messageDigest.digest();
StringBuilder fileMd5SB = new StringBuilder(data.length * 2);
for (byte b : data) {
fileMd5SB.append(HEX_CODE[(b >> 4) & 0xF]);
fileMd5SB.append(HEX_CODE[(b & 0xF)]);
}
fileMd5 = fileMd5SB.toString();
} catch (Exception e) {
LOG.error(e.getMessage(), e);
throw new FileException("文件上传失败");
@ -626,7 +671,7 @@ public class FileServiceImpl extends AbstractService implements IFileService {
throw new FileException("文件上传失败");
}
}
return true;
return fileMd5;
}
/**

View File

@ -32,7 +32,7 @@
<result property="fileUrl" column="file_url"/>
<result property="fileType" column="file_type"/>
<result property="fileSize" column="file_size"/>
<result property="fileUrl" column="file_url"/>
<result property="filePath" column="file_path"/>
<result property="fileSummary" column="file_summary"/>
<result property="isBack" column="is_back"/>
</resultMap>
@ -111,7 +111,19 @@
<!-- 获取文件 -->
<select id="getFile" parameterType="map" resultMap="filePO">
SELECT
*
file_id,
file_name,
file_path,
file_url,
file_type,
file_size,
file_summary,
is_back,
creator,
gmt_create,
modifier,
gmt_modified,
is_delete
FROM
sys_file
WHERE
@ -123,7 +135,19 @@
<!-- 文件列表 -->
<select id="listFile" parameterType="map" resultMap="fileDTO">
SELECT
*
file_id,
file_name,
file_path,
file_url,
file_type,
file_size,
file_summary,
is_back,
creator,
gmt_create,
modifier,
gmt_modified,
is_delete
FROM
sys_file
WHERE
@ -132,6 +156,10 @@
AND
file_name LIKE CONCAT('%', #{keywords}, '%')
</if>
<if test="fileSummary != null and fileSummary != ''">
AND
file_summary = #{fileSummary}
</if>
<if test="startTime != null and startTime != ''">
AND
LEFT(gmt_create, 10) <![CDATA[ >= ]]> #{startTime}
@ -156,7 +184,19 @@
<!-- 文件列表 -->
<select id="listFileInfo" parameterType="map" resultMap="fileInfoDTO">
SELECT
*
file_id,
file_name,
file_path,
file_url,
file_type,
file_size,
file_summary,
is_back,
creator,
gmt_create,
modifier,
gmt_modified,
is_delete
FROM
sys_file
WHERE
@ -185,7 +225,19 @@
<!-- 获取文件列表(带路径) -->
<select id="listFileInfoWithPath" parameterType="map" resultMap="fileInfoWithPathDTO">
SELECT
*
file_id,
file_name,
file_path,
file_url,
file_type,
file_size,
file_summary,
is_back,
creator,
gmt_create,
modifier,
gmt_modified,
is_delete
FROM
sys_file
WHERE
@ -199,4 +251,28 @@
</if>
</select>
<!-- 文件列表 -->
<select id="listFileByMd5" parameterType="java.lang.String" resultMap="fileInfoDTO">
SELECT
file_id,
file_name,
file_path,
file_url,
file_type,
file_size,
file_summary,
is_back,
creator,
gmt_create,
modifier,
gmt_modified,
is_delete
FROM
sys_file
WHERE
is_delete = 0
AND
file_summary = #{_parameter}
</select>
</mapper>