在C#中,如何从byte []中知道文件类型?

And*_*nda 28 asp.net-mvc content-type bytearray c#-3.0

我从上传的文件中填充了一个字节数组.但是,在代码的另一部分,我需要知道从byte []上传的这个文件类型,所以我可以向浏览器呈现正确的内容类型!

谢谢!!

mro*_*ach 20

如前所述,MIME魔术是唯一的方法.许多平台提供最新且强大的MIME魔术文件和代码来有效地执行此操作.在没有任何第三方代码的.NET中执行此操作的唯一方法是使用FindMimeFromDataurlmon.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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这使用Internet Explorer MIME检测器.这与IE用于发送MIME类型以及上载文件的代码相同.您可以看到urlmon.dll支持的MIME类型列表.有一点需要注意的就是image/pjpegimage/x-png它们是非标准的.在我的代码中,我用image/jpeg和替换这些image/png.

  • 有趣的是,重构前的代码与重构后的代码完全相同.对那些指出别人的错误但显然不能自己处理复制/粘贴的人来说,这不是好兆头.有点凹了他的可信度不是吗?:) (3认同)

Car*_*any 9

不确定,但也许你应该调查魔术数字.

更新: 阅读它,我不认为它是非常可靠的.

  • `FindMimeData`甚至没有检测到像'audio/mp3`那样基本的东西,所以如果你在26种类型之外发现某些东西,那么魔术数字是唯一的选择.你能详细说明为什么你认为它不可靠吗? (2认同)

小智 8

您无法从字节流中知道它,但您可以在最初填充时存储MIME类型byte[].

  • 一般来说,你不能.但是,您可以使用启发式方法检查幻数并以很高的概率猜测内容类型(如UNIX中的`file`命令所做的那样).你可以查看它的来源. (3认同)

Tho*_*que 7

简短的回答:你做不到

更长的答案:通常,程序使用文件扩展名来了解他们正在处理的文件类型.如果你没有那个扩展名,你只能猜测...例如,你可以查看前几个字节并检查你是否识别一个众所周知的标题(例如XML声明标记,或位图或JPEG标题) ).但最终总是猜测:如果没有一些元数据或有关内容的信息,一个字节数组就没有意义......


Yas*_*del 7

如果您知道文件名的扩展名,则 System.Web.MimeMapping 可能会起作用:

MimeMapping.GetMimeMapping(fileDisplayNameWithExtension)
Run Code Online (Sandbox Code Playgroud)

我在 MVC Action 中使用它,如下所示:

return File(fileDataByteArray, MimeMapping.GetMimeMapping(fileDisplayNameWithExtension), fileDisplayNameWithExtension);
Run Code Online (Sandbox Code Playgroud)


yaz*_*pro 6

如果您知道它是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;
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 我很确定会在第二个 `using` 中抛出异常。 (3认同)