Commit a5d16c11e8a63db84ff9597f9807e9c3d914ccf8

Authored by jiangqiang
1 parent c64295f4

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

yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/utils/FileTypeUtils.java
@@ -4,8 +4,6 @@ import com.alibaba.ttl.TransmittableThreadLocal; @@ -4,8 +4,6 @@ import com.alibaba.ttl.TransmittableThreadLocal;
4 import lombok.SneakyThrows; 4 import lombok.SneakyThrows;
5 import org.apache.tika.Tika; 5 import org.apache.tika.Tika;
6 6
7 -import java.io.ByteArrayInputStream;  
8 -  
9 /** 7 /**
10 * 文件类型 Utils 8 * 文件类型 Utils
11 * 9 *
@@ -16,14 +14,35 @@ public class FileTypeUtils { @@ -16,14 +14,35 @@ public class FileTypeUtils {
16 private static final ThreadLocal<Tika> TIKA = TransmittableThreadLocal.withInitial(Tika::new); 14 private static final ThreadLocal<Tika> TIKA = TransmittableThreadLocal.withInitial(Tika::new);
17 15
18 /** 16 /**
19 - * 获得文件的 mineType 17 + * 获得文件的 mineType,对于doc,jar等文件会有误差
20 * 18 *
21 - * @param data 文件内容  
22 - * @return mineType 19 + * @param data 包含文件开头几千个字节的字节数组
  20 + * @return mineType 无法识别时会返回“application/octet-stream”
23 */ 21 */
24 @SneakyThrows 22 @SneakyThrows
25 public static String getMineType(byte[] data) { 23 public static String getMineType(byte[] data) {
26 - return TIKA.get().detect(new ByteArrayInputStream(data)); 24 + return TIKA.get().detect(data);
  25 + }
  26 +
  27 + /**
  28 + * 已知文件名,获取文件类型,在某些情况下比通过字节数组准确,例如使用jar文件时,通过名字更为准确
  29 + *
  30 + * @param name 文件名
  31 + * @return mineType 无法识别时会返回“application/octet-stream”
  32 + */
  33 + public static String getMineType(String name) {
  34 + return TIKA.get().detect(name);
  35 + }
  36 +
  37 + /**
  38 + * 在拥有文件和数据的情况下,最好使用此方法,最为准确
  39 + *
  40 + * @param data 包含文件开头几千个字节的字节数组
  41 + * @param name 文件名
  42 + * @return mineType 无法识别时会返回“application/octet-stream”
  43 + */
  44 + public static String getMineType(byte[] data, String name) {
  45 + return TIKA.get().detect(data, name);
27 } 46 }
28 47
29 } 48 }
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java
1 package cn.iocoder.yudao.module.infra.service.file; 1 package cn.iocoder.yudao.module.infra.service.file;
2 2
  3 +import cn.hutool.core.io.FileTypeUtil;
  4 +import cn.hutool.core.io.file.FileNameUtil;
3 import cn.hutool.core.lang.Assert; 5 import cn.hutool.core.lang.Assert;
4 import cn.hutool.core.util.StrUtil; 6 import cn.hutool.core.util.StrUtil;
5 import cn.hutool.crypto.digest.DigestUtil; 7 import cn.hutool.crypto.digest.DigestUtil;
@@ -13,6 +15,7 @@ import lombok.SneakyThrows; @@ -13,6 +15,7 @@ import lombok.SneakyThrows;
13 import org.springframework.stereotype.Service; 15 import org.springframework.stereotype.Service;
14 16
15 import javax.annotation.Resource; 17 import javax.annotation.Resource;
  18 +import java.io.ByteArrayInputStream;
16 19
17 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 20 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
18 import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS; 21 import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
@@ -40,10 +43,16 @@ public class FileServiceImpl implements FileService { @@ -40,10 +43,16 @@ public class FileServiceImpl implements FileService {
40 @SneakyThrows 43 @SneakyThrows
41 public String createFile(String name, String path, byte[] content) { 44 public String createFile(String name, String path, byte[] content) {
42 // 计算默认的 path 名 45 // 计算默认的 path 名
43 - String type = FileTypeUtils.getMineType(content); 46 + String type = FileTypeUtils.getMineType(content, name);
44 if (StrUtil.isEmpty(path)) { 47 if (StrUtil.isEmpty(path)) {
45 - path = DigestUtil.md5Hex(content)  
46 - + '.' + StrUtil.subAfter(type, '/', true); // 文件的后缀 48 + String sha256Hex = DigestUtil.sha256Hex(content);
  49 + /* 如果存在name,则优先使用name的后缀 */
  50 + if (StrUtil.isNotBlank(name)) {
  51 + String extName = FileNameUtil.extName(name);
  52 + path = StrUtil.isBlank(extName) ? sha256Hex : sha256Hex + "." + extName;
  53 + } else {
  54 + path = sha256Hex + '.' + FileTypeUtil.getType(new ByteArrayInputStream(content), name);
  55 + }
47 } 56 }
48 // 如果 name 为空,则使用 path 填充 57 // 如果 name 为空,则使用 path 填充
49 if (StrUtil.isEmpty(name)) { 58 if (StrUtil.isEmpty(name)) {