asp.net-mvc 在 C# 中,如何从字节 [] 中知道文件类型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1654846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In C#, how can I know the file type from a byte[]?
提问by AndreMiranda
I have a byte array filled from a file uploaded. But, in another part of the code, I need to know this file type uploaded from the byte[] so I can render the correct content-type to browser!
我有一个从上传的文件填充的字节数组。但是,在代码的另一部分,我需要知道从 byte[] 上传的这个文件类型,这样我才能将正确的内容类型呈现给浏览器!
Thanks!!
谢谢!!
采纳答案by Carles Company
Not sure, but maybe you should investigate about magic numbers.
不确定,但也许您应该调查一下magic numbers。
Update:Reading about it, I don't think it's very reliable though.
更新:阅读它,但我认为它不是很可靠。
回答by mroach
As mentioned, MIME magic is the only way to do this. Many platforms provide up-to-date and robust MIME magic files and code to do this efficiently. The only way to do this in .NET without any 3rd party code is to use FindMimeFromDatafrom urlmon.dll. Here's how:
如前所述,MIME 魔术是实现此目的的唯一方法。许多平台提供了最新且强大的 MIME 魔术文件和代码来有效地执行此操作。在没有任何第三方代码的情况下,在 .NET 中执行此操作的唯一方法是FindMimeFromData从 urlmon.dll 中使用。就是这样:
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;
}
}
This uses the Internet Explorer MIME detector. This is the same code used by IE to send a MIME type along with uploaded files. You can see the list of MIME types supported by urlmon.dll. One thing to watch out for is image/pjpegand image/x-pngwhich are non-standard. In my code I replace these with image/jpegand image/png.
这使用 Internet Explorer MIME 检测器。这与 IE 用于发送 MIME 类型以及上传文件的代码相同。您可以查看urlmon.dll 支持的 MIME 类型列表。有一点需要注意的就是image/pjpeg和image/x-png它们是非标准的。在我的代码中,我将它们替换为image/jpegand image/png。
回答by Carles Company
You can't know it from the byte stream, but you can store the MIME type when you initially populate the byte[].
您无法从字节流中知道它,但是您可以在最初填充byte[].
回答by Thomas Levesque
Short answer: you can't
简短的回答:你不能
Longer answer: Usually, programs use the file extension to know what type of file they're dealing with. If you don't have that extension, you can only make guesses... for instance, you could look at the first few bytes and check if you recognize a well-known header (XML declaration tag for instance, or bitmap or JPEG header). But that will always be a guess in the end : without some metadata or information about the content, an array of bytes is just meaningless...
更长的答案:通常,程序使用文件扩展名来了解他们正在处理的文件类型。如果您没有该扩展名,则只能进行猜测……例如,您可以查看前几个字节并检查您是否识别出众所周知的标头(例如 XML 声明标记,或位图或 JPEG 标头) )。但这最终总是一个猜测:如果没有一些元数据或有关内容的信息,字节数组就毫无意义......
回答by yazanpro
If you know it's a System.Drawing.Image, you can do:
如果你知道它是一个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;
}
}
回答by Yasser Sobhdel
If you know extension of the file name, may be System.Web.MimeMapping will do the trick:
如果您知道文件名的扩展名,则 System.Web.MimeMapping 可能会起作用:
MimeMapping.GetMimeMapping(fileDisplayNameWithExtension)
I used it in MVC Action like this:
我在 MVC Action 中使用它,如下所示:
return File(fileDataByteArray, MimeMapping.GetMimeMapping(fileDisplayNameWithExtension), fileDisplayNameWithExtension);
回答by DanO
Reminds me of back in the day we, er um "some people" used to share 50MB rar files on the early free image hosting sites, by just adding the .gif extension to the .rar filename.
让我想起了那天我们,呃“有些人”曾经在早期的免费图像托管网站上共享 50MB 的 rar 文件,只需将 .gif 扩展名添加到 .rar 文件名。
Clearly if you are public facing and your are expecting a certain file type, and you have to be sure it is that file type, then you can't just trust the extension.
显然,如果您是面向公众的并且希望使用某种文件类型,并且您必须确定它是该文件类型,那么您不能只相信扩展名。
On the other hand, if your app would have no reason to distrust the the uploaded extension and or MIME type, then just get those when the file is uploaded like the answers you received from @rossfabircant and @RandolphPotter. create a type that has the byte[], as well as the original extension or mimetype, and pass that around.
另一方面,如果您的应用程序没有理由不信任上传的扩展名和/或 MIME 类型,那么只需在上传文件时获取它们,就像您从 @rossfabircant 和 @RandolphPotter 收到的答案一样。创建一个具有 byte[] 以及原始扩展名或 mimetype 的类型,并将其传递。
If you need to verify that the file is actually a certain expected type like a valid .jpeg, or .png you can try to interpret the file as those types and see if it opens successfully. (System.Drawing.Imaging.ImageFormat)
如果您需要验证文件实际上是某种预期类型,例如有效的 .jpeg 或 .png,您可以尝试将文件解释为这些类型并查看它是否成功打开。(System.Drawing.Imaging.ImageFormat)
If you are trying to classify the file only from the binary contents, and it could be any format in the whole wide world, that is really a tough, open-ended problem and there is no 100% reliable way to do it. You could invoke TrIDagainst it, and there are likely similar forensics tools used by law enforcement investigators if you can find (and afford) them.
如果您试图仅从二进制内容中对文件进行分类,并且它可以是整个世界中的任何格式,那么这确实是一个棘手的开放式问题,并且没有 100% 可靠的方法来做到这一点。您可以针对它调用TrID,如果您能找到(并负担得起),执法调查人员可能会使用类似的取证工具。
If you don't have to do it the hard way, don't.
如果您不必以艰难的方式去做,请不要这样做。
回答by RossFabricant
You don't want to do it that way. Call Path.GetExtension when the file is uploaded, and pass the extension around with the byte[].
你不想那样做。上传文件时调用 Path.GetExtension,并使用 byte[] 传递扩展名。
回答by Oskuro
If you have a limited number of expected file types you want to support, magic numbers can be the way to go.
如果您想要支持的预期文件类型数量有限,那么魔术数字可能是您要走的路。
A simple way to check is to just open example files with a text/hex editor, and study the leading bytes to see if there is something there you can use to differentiate/discard files from the supported set.
一种简单的检查方法是使用文本/十六进制编辑器打开示例文件,并研究前导字节以查看是否有可用于区分/丢弃文件与受支持文件集的内容。
If, on the other hand, you are looking to recognize any arbitrary file type, yeah, as everyone has stated already, tough.
另一方面,如果您希望识别任意文件类型,是的,正如每个人已经说过的那样,很难。
回答by Muhammad Omar ElShourbagy
Using the System.Drawing.Image 'RawFormat.Guid' Property you can detect MIME Type of Images.
使用 System.Drawing.Image 'RawFormat.Guid' 属性,您可以检测图像的 MIME 类型。
but i am not sure how to find other File Types.
但我不确定如何找到其他文件类型。
http://www.java2s.com/Code/CSharp/Network/GetImageMimeType.htm
http://www.java2s.com/Code/CSharp/Network/GetImageMimeType.htm
UPDATE:you may try taking a look on this post
更新:您可以尝试查看这篇文章
Using .NET, how can you find the mime type of a file based on the file signature not the extension

