优化文件的 type 识别与存储

This commit is contained in:
YunaiV
2022-07-10 00:00:56 +08:00
parent fec84f2682
commit 34ea1db585
5 changed files with 55 additions and 18 deletions

View File

@@ -1,9 +1,14 @@
package cn.iocoder.yudao.framework.common.util.io;
import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import lombok.SneakyThrows;
import java.io.ByteArrayInputStream;
import java.io.File;
/**
@@ -58,4 +63,22 @@ public class FileUtils {
return file;
}
/**
* 生成文件路径
*
* @param content 文件内容
* @param originalName 原始文件名
* @return path唯一不可重复
*/
public static String generatePath(byte[] content, String originalName) {
String sha256Hex = DigestUtil.sha256Hex(content);
// 情况一:如果存在 name则优先使用 name 的后缀
if (StrUtil.isNotBlank(originalName)) {
String extName = FileNameUtil.extName(originalName);
return StrUtil.isBlank(extName) ? sha256Hex : sha256Hex + "." + extName;
}
// 情况二:基于 content 计算
return sha256Hex + '.' + FileTypeUtil.getType(new ByteArrayInputStream(content));
}
}

View File

@@ -4,8 +4,6 @@ import com.alibaba.ttl.TransmittableThreadLocal;
import lombok.SneakyThrows;
import org.apache.tika.Tika;
import java.io.ByteArrayInputStream;
/**
* 文件类型 Utils
*
@@ -16,14 +14,35 @@ public class FileTypeUtils {
private static final ThreadLocal<Tika> TIKA = TransmittableThreadLocal.withInitial(Tika::new);
/**
* 获得文件的 mineType
* 获得文件的 mineType对于docjar等文件会有误差
*
* @param data 文件内容
* @return mineType
* @param data 包含文件开头几千个字节的字节数组
* @return mineType 无法识别时会返回“application/octet-stream”
*/
@SneakyThrows
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);
}
}