为了账号安全,请及时绑定邮箱和手机立即绑定

获取不使用文件扩展名的文件类型 c#

获取不使用文件扩展名的文件类型 c#

C#
梵蒂冈之花 2021-12-25 18:29:51
我知道以前有人问过这个问题,但两种解决方案都不适合我。我想知道上传到我的服务器(通过 .ashx)的文件是 .xlsx、.xls 还是 .csv 类型。我尝试使用此处列出的幻数,但例如,如果我将 .msi 的扩展名更改为 .xls,则该文件将被识别为 .xls...以下代码说明了我所说的内容:private bool IsValidFileType(HttpPostedFile file){    using (var memoryStream = new MemoryStream())    {        file.InputStream.CopyTo(memoryStream);        byte[] buffer = memoryStream.ToArray();        //Check exe and dll        if (buffer[0] == 0x4D && buffer[1] == 0x5A)        {            return false;        }        //Check xlsx        if (buffer.Length >= 3 &&            buffer[0] == 0x50 && buffer[1] == 0x4B &&            buffer[2] == 0x03 && buffer[3] == 0x04 ||            buffer[0] == 0x50 && buffer[1] == 0x4B &&            buffer[2] == 0x05 && buffer[3] == 0x06)        {            return true;        }        //Check xls        if (buffer.Length >= 7 &&            buffer[0] == 0xD0 && buffer[1] == 0xCF &&            buffer[2] == 0x11 && buffer[3] == 0xE0 &&            buffer[4] == 0xA1 && buffer[5] == 0xB1 &&            buffer[6] == 0x1A && buffer[7] == 0xE1)        {            return true;        }        return false;    }}然后我尝试使用urlmon.dll,类似于以下内容,但它仍然将文件识别为 .xls    [DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]    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);我在想,也许我应该尝试使用一些库(例如ExcelDataReader)打开上传的文件,但我不确定这是否是最佳方法。任何帮助,将不胜感激。
查看完整描述

3 回答

?
catspeake

TA贡献1111条经验 获得超0个赞

如果它不是 Excel 文件,如何通过EPPlusof打开文件 ExcelInterop并捕获异常


FileInfo fileInfo = new FileInfo(filePath);

ExcelPackage package = null;

try

{

    package = new ExcelPackage(fileInfo);

}

catch(Exception exception)

{

}

或者有第三方(未测试)验证文件类型。


FileInfo file = new FileInfo("C:\Hello.pdf");

if ( file.isExcel())

    Console.WriteLine("File is PDF");


查看完整回答
反对 回复 2021-12-25
?
胡子哥哥

TA贡献1825条经验 获得超6个赞

我尝试使用此处列出的幻数,但例如,如果我将 .msi 的扩展名更改为 .xls,则该文件将被识别为 .xls...以下代码说明了我所说的内容:

是的,确实如此,您在检查文件签名时唯一可以确定的是文件所基于的格式。因此,对于“.xls”文件,您将检测到该文件是复合二进制格式。但是,正如您注意到的,此格式用于“.msi”文件,也用于“.doc”、“.ppt”等。

此外,您的“.xlsx”检测也是如此,它只是检查文件是否为 zip 格式,并且在“.zip”、“.docx”、“.ods”等中会找到相同的签名.

因此,您可以检查文件的签名并通过这两种格式的文件,但是“.csv”呢?在这里,您可以拥有各种字节值,因为它只是一个纯文本,没有签名。

无论如何,我认为真正的问题是您使用这些 Excel 文件的目标是什么?你需要进一步处理它们还是什么?
如果您需要进一步处理它们,那么您应该依赖读取该文件的失败机制。因此,无论您选择读取文件的哪个库,都很可能会因为文件的“无法识别的格式”或“无法识别的结构”而引发异常。

我所说的“无法识别的结构”是什么意思,例如在“.xls”文件中,它应该有名为“Workbook”、“SummaryInformation”等的流。


查看完整回答
反对 回复 2021-12-25
?
翻阅古今

TA贡献1780条经验 获得超5个赞

文件本身就是数据。文件扩展名允许您的系统相应地解释该数据。如果没有文件扩展名,就无法绝对确定您正在查看哪种文件类型。(除非您使用的是有限的文件类型子集)

但是,您可以从数据中推断出它可能是哪个文件扩展名。Thierry V 引用的项目已过时且未维护。

相反,您可能想要查看像TrID这样的工具,它使用不断增长的文件类型库。此工具将分析文件并给出最可能的文件类型的排名。就像我之前说的,它只能以有限的确定性告诉您它可能是哪种文件类型。


查看完整回答
反对 回复 2021-12-25
  • 3 回答
  • 0 关注
  • 247 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信