优化获取mimetype方式,优化生成path方式

This commit is contained in:
jiangqiang 2022-07-09 11:27:45 +08:00
parent c64295f432
commit a5d16c11e8
2 changed files with 37 additions and 9 deletions

View File

@ -4,8 +4,6 @@ import com.alibaba.ttl.TransmittableThreadLocal;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.apache.tika.Tika; import org.apache.tika.Tika;
import java.io.ByteArrayInputStream;
/** /**
* 文件类型 Utils * 文件类型 Utils
* *
@ -16,14 +14,35 @@ public class FileTypeUtils {
private static final ThreadLocal<Tika> TIKA = TransmittableThreadLocal.withInitial(Tika::new); private static final ThreadLocal<Tika> TIKA = TransmittableThreadLocal.withInitial(Tika::new);
/** /**
* 获得文件的 mineType * 获得文件的 mineType对于docjar等文件会有误差
* *
* @param data 文件内容 * @param data 包含文件开头几千个字节的字节数组
* @return mineType * @return mineType 无法识别时会返回application/octet-stream
*/ */
@SneakyThrows @SneakyThrows
public static String getMineType(byte[] data) { public static String getMineType(byte[] data) {
return TIKA.get().detect(new ByteArrayInputStream(data)); return TIKA.get().detect(data);
}
/**
* 已知文件名获取文件类型在某些情况下比通过字节数组准确例如使用jar文件时通过名字更为准确
*
* @param name 文件名
* @return mineType 无法识别时会返回application/octet-stream
*/
public static String getMineType(String name) {
return TIKA.get().detect(name);
}
/**
* 在拥有文件和数据的情况下最好使用此方法最为准确
*
* @param data 包含文件开头几千个字节的字节数组
* @param name 文件名
* @return mineType 无法识别时会返回application/octet-stream
*/
public static String getMineType(byte[] data, String name) {
return TIKA.get().detect(data, name);
} }
} }

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.infra.service.file; package cn.iocoder.yudao.module.infra.service.file;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil; import cn.hutool.crypto.digest.DigestUtil;
@ -13,6 +15,7 @@ import lombok.SneakyThrows;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
@ -40,10 +43,16 @@ public class FileServiceImpl implements FileService {
@SneakyThrows @SneakyThrows
public String createFile(String name, String path, byte[] content) { public String createFile(String name, String path, byte[] content) {
// 计算默认的 path // 计算默认的 path
String type = FileTypeUtils.getMineType(content); String type = FileTypeUtils.getMineType(content, name);
if (StrUtil.isEmpty(path)) { if (StrUtil.isEmpty(path)) {
path = DigestUtil.md5Hex(content) String sha256Hex = DigestUtil.sha256Hex(content);
+ '.' + StrUtil.subAfter(type, '/', true); // 文件的后缀 /* 如果存在name则优先使用name的后缀 */
if (StrUtil.isNotBlank(name)) {
String extName = FileNameUtil.extName(name);
path = StrUtil.isBlank(extName) ? sha256Hex : sha256Hex + "." + extName;
} else {
path = sha256Hex + '.' + FileTypeUtil.getType(new ByteArrayInputStream(content), name);
}
} }
// 如果 name 为空则使用 path 填充 // 如果 name 为空则使用 path 填充
if (StrUtil.isEmpty(name)) { if (StrUtil.isEmpty(name)) {