In C#, how can I know the file type from a byte[]?

后端 未结 10 1218
不思量自难忘°
不思量自难忘° 2020-11-28 08:28

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

相关标签:
10条回答
  • 2020-11-28 09:04

    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...

    0 讨论(0)
  • 2020-11-28 09:07

    Using the System.Drawing.Image 'RawFormat.Guid' Property you can detect MIME Type of Images.

    but i am not sure how to find other File Types.

    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

    0 讨论(0)
  • 2020-11-28 09:11

    If you know it's a System.Drawing.Image, you can do:

    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;
       }
    }
    
    0 讨论(0)
  • 2020-11-28 09:18

    You can't know it from the byte stream, but you can store the MIME type when you initially populate the byte[].

    0 讨论(0)
  • 2020-11-28 09:19

    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 FindMimeFromData from urlmon.dll. Here's how:

    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/pjpeg and image/x-png which are non-standard. In my code I replace these with image/jpeg and image/png.

    0 讨论(0)
  • 2020-11-28 09:19

    If you know extension of the file name, may be System.Web.MimeMapping will do the trick:

    MimeMapping.GetMimeMapping(fileDisplayNameWithExtension)
    

    I used it in MVC Action like this:

    return File(fileDataByteArray, MimeMapping.GetMimeMapping(fileDisplayNameWithExtension), fileDisplayNameWithExtension);
    
    0 讨论(0)
提交回复
热议问题