【发布时间】:2019-02-06 13:57:35
【问题描述】:
我知道以前有人问过这个问题,但是这两种解决方案都不适合我。 我想知道上传到我的服务器(通过 .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,但我不确定这是否是最好的方法。
任何帮助将不胜感激。
【问题讨论】:
-
为什么不能检查扩展名然后验证适当的魔术字节? (尽管后者不适用于 csv)
-
只是为了清楚起见:是否足以检测文件是否不是扩展名所说的应该是什么,或者您实际上需要检测它是什么类型的文件是否完全不考虑扩展?
-
@AlexK。我目前正在这样做,但是,如果我有一个 .msi 文件,然后将其扩展名更改为 .xls,即使我检查了适当的魔术字节,结果仍然是相同的(似乎 .msi 头字节与.xls)
-
@Fildor 我无法信任文件扩展名,因为用户可以上传带有 .xls 扩展名的 .msi
-
是的,我明白了。所以你只需要“欺诈检测”。如果实际文件类型 != ext 文件类型,取消操作并返回错误是可以的,对吧?
标签: c# excel mime-types mime