我从上传的文件中填充了一个字节数组。但是,在代码的另一部分中,我需要知道从byte []上传的这种文件类型,这样我才能将正确的内容类型呈现给浏览器!
谢谢!
答案 0 :(得分:20)
如前所述,MIME魔术是唯一的方法。许多平台提供最新且强大的MIME魔术文件和代码来有效地执行此操作。在没有任何第三方代码的.NET中执行此操作的唯一方法是使用urlmon.dll中的FindMimeFromData
。方法如下:
public static int MimeSampleSize = 256;
public static string DefaultMimeType = "application/octet-stream";
[DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
private extern static uint FindMimeFromData(
uint pBC,
[MarshalAs(UnmanagedType.LPStr)] string pwzUrl,
[MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
uint cbSize,
[MarshalAs(UnmanagedType.LPStr)] string pwzMimeProposed,
uint dwMimeFlags,
out uint ppwzMimeOut,
uint dwReserverd
);
public static string GetMimeFromBytes(byte[] data) {
try {
uint mimeType;
FindMimeFromData(0, null, data, (uint)MimeSampleSize, null, 0, out mimeType, 0);
var mimePointer = new IntPtr(mimeType);
var mime = Marshal.PtrToStringUni(mimePointer);
Marshal.FreeCoTaskMem(mimePointer);
return mime ?? DefaultMimeType;
}
catch {
return DefaultMimeType;
}
}
这使用Internet Explorer MIME检测器。这与IE用于发送MIME类型以及上载文件的代码相同。你可以看到list of MIME types supported by urlmon.dll。需要注意的一点是image/pjpeg
和image/x-png
,这是非标准的。在我的代码中,我将其替换为image/jpeg
和image/png
。
答案 1 :(得分:9)
不确定,但也许您应该调查magic numbers。
<强>更新强> 读到它,我认为它不是很可靠。
答案 2 :(得分:8)
您无法从字节流中知道它,但您可以在最初填充byte[]
时存储MIME类型。
答案 3 :(得分:7)
简短回答:你不能
更长的答案:通常,程序使用文件扩展名来了解他们正在处理的文件类型。如果你没有那个扩展名,你只能猜测...例如,你可以查看前几个字节并检查你是否识别一个众所周知的标题(例如XML声明标记,或位图或JPEG标题) )。但最终总是猜测:如果没有一些元数据或有关内容的信息,一个字节数组就没有意义......
答案 4 :(得分:4)
如果你知道它是System.Drawing.Image
,你可以这样做:
public static string GeMimeTypeFromImageByteArray(byte[] byteArray)
{
using (MemoryStream stream = new MemoryStream(byteArray))
using (Image image = Image.FromStream(stream))
{
return ImageCodecInfo.GetImageEncoders().First(codec => codec.FormatID == image.RawFormat.Guid).MimeType;
}
}
答案 5 :(得分:2)
让我回想起当天我们,呃“有些人”曾经在早期免费图片托管网站上分享50MB rar文件,只需在.rar文件名中添加.gif扩展名即可。
显然,如果您面向公众并期望某种文件类型,并且您必须确定它是该文件类型,那么您不能只信任该扩展名。
另一方面,如果您的应用没有理由不信任上传的扩展名和/或MIME类型,那么只需在文件上传时获取,就像您从@rossfabircant和@RandolphPotter收到的答案一样。创建一个具有byte []的类型,以及原始扩展名或mimetype,并传递它。
如果您需要验证文件实际上是某个预期类型,如有效的.jpeg或.png,您可以尝试将该文件解释为这些类型,并查看它是否成功打开。 (System.Drawing.Imaging.ImageFormat)
如果您尝试仅从二进制内容对文件进行分类,并且它可能是整个世界中的任何格式,那实际上是一个棘手的开放式问题,并且没有100%可靠的方法来实现它。您可以针对它调用TrID,如果您能找到(并且负担得起),执法调查人员可能会使用类似的取证工具。
如果您不必这么做,请不要。
答案 6 :(得分:2)
如果知道文件名的扩展名,则可以使用System.Web.MimeMapping来解决问题:
MimeMapping.GetMimeMapping(fileDisplayNameWithExtension)
我在MVC Action中像这样使用它:
return File(fileDataByteArray, MimeMapping.GetMimeMapping(fileDisplayNameWithExtension), fileDisplayNameWithExtension);
答案 7 :(得分:1)
你不想这样做。上传文件时调用Path.GetExtension,并使用byte []传递扩展名。
答案 8 :(得分:0)
如果您希望支持有限数量的预期文件类型,可以使用幻数。
一种简单的检查方法是使用文本/十六进制编辑器打开示例文件,并研究前导字节以查看是否有可用于区分/丢弃文件与支持的集合的文件。
另一方面,如果您想要识别任意文件类型,是的,正如每个人已经说过的那样,很难。
答案 9 :(得分:0)
使用System.Drawing.Image'RawFormat.Guid'属性,您可以检测图像的MIME类型。
但我不确定如何找到其他文件类型。
http://www.java2s.com/Code/CSharp/Network/GetImageMimeType.htm
更新:您可以尝试查看此帖子
Using .NET, how can you find the mime type of a file based on the file signature not the extension