获取不使用文件扩展名的文件类型c#
Get file type not using the file extension c#
我知道之前有人问过这个问题,但是这两种解决方案都不适合我。
我想知道上传到我的服务器(通过 .ashx)的文件是 .xlsx、.xls 还是 .csv 类型。
我尝试使用列出的幻数 here,但是如果我将 .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);
public static string GetMimeFromFile(string file)
{
if (!File.Exists(file))
throw new FileNotFoundException(file + " not found");
int MaxContent = (int)new FileInfo(file).Length;
if (MaxContent > 4096) MaxContent = 4096;
FileStream fs = File.OpenRead(file);
byte[] buf = new byte[MaxContent];
fs.Read(buf, 0, MaxContent);
fs.Close();
int result = FindMimeFromData(IntPtr.Zero, file, buf, MaxContent, null, 0, out IntPtr mimeout, 0);
if (result != 0)
throw Marshal.GetExceptionForHR(result);
string mime = Marshal.PtrToStringUni(mimeout);
Marshal.FreeCoTaskMem(mimeout);
return mime;
}
我在想也许我应该尝试用一些库打开上传的文件,例如 ExcelDataReader,但我不确定这是否是最好的方法。
如有任何帮助,我们将不胜感激。
如何通过 Interop
的 EPPlus
打开文件 Excel 并且如果它不是 excel 文件
则捕捉异常
FileInfo fileInfo = new FileInfo(filePath);
ExcelPackage package = null;
try
{
package = new ExcelPackage(fileInfo);
}
catch(Exception exception)
{
}
或者有一个3rd party(未测试)验证文件类型。
FileInfo file = new FileInfo("C:\Hello.pdf");
if ( file.isExcel())
Console.WriteLine("File is PDF");
文件本身就是数据。文件扩展名允许您的系统相应地解释该数据。没有文件扩展名,就无法绝对确定您正在查看的文件类型。 (除非您使用的是有限的文件类型子集)
但是您可以从数据中推断出它可能是哪个文件扩展名。 Thierry V 引用的项目已过时且未维护。
您可能想看看像 TrID 这样的工具,它使用不断增长的文件类型库。
该工具将分析文件并给出最可能的文件类型的排名。
正如我之前所说,它只能有限地告诉您它可能是哪种文件类型。
I tried using the magic numbers listed here, but if I for example change the extension of a .msi to .xls, the file will be recognized as .xls... The following code ilustrates what i said:
是的,确实如此,在检查文件签名时您唯一可以确定的是文件所基于的格式。因此,对于“.xls”文件,您将检测到该文件是复合二进制格式。但是,正如您所注意到的,这种格式用于“.msi”文件,也用于“.doc”、“.ppt”等文件
此外,您的“.xlsx”检测也是如此,它只是检查文件是否为 zip 格式,并且在“.zip”、“.docx”、“ .ods”等
因此,您可以检查文件的签名并通过这两种格式的文件,但是“.csv”呢?在这里,您可以有各种字节值,因为它只是纯文本,没有签名。
无论如何,我认为真正的问题是您对这些 Excel 文件的目标是什么?您需要进一步处理它们还是什么?
如果您需要进一步处理它们,那么您应该依赖正在读取该文件的机制的失败机制。因此,无论您选择哪个库来读取文件,很可能会因为文件的 "unrecognized format" 或 "unrecognized structure" 而引发异常。
"unrecognized structure" 我的意思是,例如在“.xls”文件中,它应该具有名为 "Workbook"、"SummaryInformation" 等的流
我知道之前有人问过这个问题,但是这两种解决方案都不适合我。 我想知道上传到我的服务器(通过 .ashx)的文件是 .xlsx、.xls 还是 .csv 类型。
我尝试使用列出的幻数 here,但是如果我将 .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);
public static string GetMimeFromFile(string file)
{
if (!File.Exists(file))
throw new FileNotFoundException(file + " not found");
int MaxContent = (int)new FileInfo(file).Length;
if (MaxContent > 4096) MaxContent = 4096;
FileStream fs = File.OpenRead(file);
byte[] buf = new byte[MaxContent];
fs.Read(buf, 0, MaxContent);
fs.Close();
int result = FindMimeFromData(IntPtr.Zero, file, buf, MaxContent, null, 0, out IntPtr mimeout, 0);
if (result != 0)
throw Marshal.GetExceptionForHR(result);
string mime = Marshal.PtrToStringUni(mimeout);
Marshal.FreeCoTaskMem(mimeout);
return mime;
}
我在想也许我应该尝试用一些库打开上传的文件,例如 ExcelDataReader,但我不确定这是否是最好的方法。
如有任何帮助,我们将不胜感激。
如何通过 Interop
的 EPPlus
打开文件 Excel 并且如果它不是 excel 文件
FileInfo fileInfo = new FileInfo(filePath);
ExcelPackage package = null;
try
{
package = new ExcelPackage(fileInfo);
}
catch(Exception exception)
{
}
或者有一个3rd party(未测试)验证文件类型。
FileInfo file = new FileInfo("C:\Hello.pdf");
if ( file.isExcel())
Console.WriteLine("File is PDF");
文件本身就是数据。文件扩展名允许您的系统相应地解释该数据。没有文件扩展名,就无法绝对确定您正在查看的文件类型。 (除非您使用的是有限的文件类型子集)
但是您可以从数据中推断出它可能是哪个文件扩展名。 Thierry V 引用的项目已过时且未维护。
您可能想看看像 TrID 这样的工具,它使用不断增长的文件类型库。 该工具将分析文件并给出最可能的文件类型的排名。 正如我之前所说,它只能有限地告诉您它可能是哪种文件类型。
I tried using the magic numbers listed here, but if I for example change the extension of a .msi to .xls, the file will be recognized as .xls... The following code ilustrates what i said:
是的,确实如此,在检查文件签名时您唯一可以确定的是文件所基于的格式。因此,对于“.xls”文件,您将检测到该文件是复合二进制格式。但是,正如您所注意到的,这种格式用于“.msi”文件,也用于“.doc”、“.ppt”等文件
此外,您的“.xlsx”检测也是如此,它只是检查文件是否为 zip 格式,并且在“.zip”、“.docx”、“ .ods”等
因此,您可以检查文件的签名并通过这两种格式的文件,但是“.csv”呢?在这里,您可以有各种字节值,因为它只是纯文本,没有签名。
无论如何,我认为真正的问题是您对这些 Excel 文件的目标是什么?您需要进一步处理它们还是什么?
如果您需要进一步处理它们,那么您应该依赖正在读取该文件的机制的失败机制。因此,无论您选择哪个库来读取文件,很可能会因为文件的 "unrecognized format" 或 "unrecognized structure" 而引发异常。
"unrecognized structure" 我的意思是,例如在“.xls”文件中,它应该具有名为 "Workbook"、"SummaryInformation" 等的流