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

我知道以前有人问过这个问题,但两种解决方案都不适合我。我想知道上传到我的服务器(通过 .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)打开上传的文件,但我不确定这是否是最佳方法。


任何帮助,将不胜感激。


梵蒂冈之花
浏览 249回答 3
3回答

catspeake

如果它不是 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");

胡子哥哥

我尝试使用此处列出的幻数,但例如,如果我将 .msi 的扩展名更改为 .xls,则该文件将被识别为 .xls...以下代码说明了我所说的内容:是的,确实如此,您在检查文件签名时唯一可以确定的是文件所基于的格式。因此,对于“.xls”文件,您将检测到该文件是复合二进制格式。但是,正如您注意到的,此格式用于“.msi”文件,也用于“.doc”、“.ppt”等。此外,您的“.xlsx”检测也是如此,它只是检查文件是否为 zip 格式,并且在“.zip”、“.docx”、“.ods”等中会找到相同的签名.因此,您可以检查文件的签名并通过这两种格式的文件,但是“.csv”呢?在这里,您可以拥有各种字节值,因为它只是一个纯文本,没有签名。无论如何,我认为真正的问题是您使用这些 Excel 文件的目标是什么?你需要进一步处理它们还是什么?如果您需要进一步处理它们,那么您应该依赖读取该文件的失败机制。因此,无论您选择读取文件的哪个库,都很可能会因为文件的“无法识别的格式”或“无法识别的结构”而引发异常。我所说的“无法识别的结构”是什么意思,例如在“.xls”文件中,它应该有名为“Workbook”、“SummaryInformation”等的流。

翻阅古今

文件本身就是数据。文件扩展名允许您的系统相应地解释该数据。如果没有文件扩展名,就无法绝对确定您正在查看哪种文件类型。(除非您使用的是有限的文件类型子集)但是,您可以从数据中推断出它可能是哪个文件扩展名。Thierry V 引用的项目已过时且未维护。相反,您可能想要查看像TrID这样的工具,它使用不断增长的文件类型库。此工具将分析文件并给出最可能的文件类型的排名。就像我之前说的,它只能以有限的确定性告诉您它可能是哪种文件类型。
打开App,查看更多内容
随时随地看视频慕课网APP