C# Winform如何不依赖扩展名、通过文件数据识别真实文件类型
问题修复与替代方案
1 首个Mime-Detective库调用错误修复
你当前的错误原因是未通过ContentInspectorBuilder生成实际检测实例,直接将builder实例传入检测方法导致功能失效,修复后的核心代码如下:
// 类内新增ContentInspector实例字段 private ContentInspector inspectorInstance; // 构造函数里补Build逻辑 public Form1() { InitializeComponent(); openFile = new OpenFileDialog(); var inspectorBuilder = new ContentInspectorBuilder() { Definitions = new MimeDetective.Definitions.ExhaustiveBuilder() { UsageType = MimeDetective.Definitions.Licensing.UsageType.PersonalNonCommercial }.Build() }; // 提前构建检测实例,避免每次检测重复构建损耗性能 inspectorInstance = inspectorBuilder.Build(); } private String findFileType(String path) { var content = ContentReader.Default.ReadFromFile(path); var results = inspectorInstance.Inspect(content); // 取匹配优先级最高的后缀,处理无匹配的空值情况 return results.ByFileExtension().FirstOrDefault()?.Extension ?? "未知格式"; }
注意:商业使用需确认该库的授权条款
2 第二个Mime-Detective库崩溃与识别失败修复
2.1 崩溃问题修复
崩溃是因为未释放文件流,且没有处理空识别结果导致的空引用异常,修复后的代码如下:
private String findFileType(String path) { // using语法会在代码块结束后自动释放文件流,避免资源占用 using Stream fileDataStream = File.Open(path, FileMode.Open, FileAccess.Read); FileType fileType = fileDataStream.GetFileType(); // 空值判断避免空引用崩溃 return fileType?.Extension ?? "未知格式"; }
2.2 低识别率问题修复
xml、htm这类纯文本类文件没有固定的魔术数字头,仅靠魔数检测的库天然识别率低,可补充以下逻辑:
- 读取文件前100个字符,判断是否包含
<?xml、<html、<!DOCTYPE html等特征串,对应标记为xml、html格式 - 手动补全缺失的格式规则:比如flac文件头4个字节为
fLaC,可在库的格式规则列表中手动添加该规则
3 更稳定的替代实现方案
3.1 Windows原生方案
调用系统自带的Urlmon.dll中FindMimeFromData方法,无第三方依赖,兼容性好,核心实现如下:
// 引入系统API [DllImport("urlmon.dll", CharSet = CharSet.Auto)] private static extern int FindMimeFromData(IntPtr pBC, [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl, [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1, SizeParamIndex=3)] byte[] pBuffer, int cbSize, [MarshalAs(UnmanagedType.LPWStr)] string pwzMimeProposed, int dwMimeFlags, out IntPtr ppwzMimeOut, int dwReserved);
调用后获取MIME类型,再映射为对应文件后缀即可。
3.2 跨平台方案
采用基于通用magic识别数据库的开源实现,支持全平台运行,覆盖的格式类型更多,对纯文本、音视频格式的识别准确率远高于普通魔数检测库。
内容的提问来源于stack exchange,提问作者CephDigital
相关产品推荐
相关产品推荐

