การใช้. NET คุณจะค้นหาไฟล์ mime ได้อย่างไรโดยอิงจากลายเซ็นของไฟล์ไม่ใช่นามสกุล


241

ฉันกำลังมองหาวิธีง่ายๆในการรับชนิด mime ที่นามสกุลไฟล์ไม่ถูกต้องหรือไม่ได้ให้อะไรที่คล้ายกับคำถามนี้เฉพาะใน. Net


เสียงนี้คล้ายกับคำถามนี้
Greg Hewgill

22
ฉันหวังว่าฉันจะสามารถลบ "คำตอบปลอม" ทั้งหมดที่ยังคงใช้นามสกุลไฟล์เมื่อข้อกำหนดชัดเจนว่าอย่าใช้นามสกุล!
Edward Olamisan

1
นี่อาจเป็นคำถามเก่า แต่ปัญหายังคงอยู่ ฉันจะลงคะแนนทุกคำตอบที่นี่บนพื้นฐานที่พวกเขาเพียงตรวจสอบ executables Windows โดยเนื้อหา สิ่งที่เกี่ยวกับ Linux หรือ iOS executables หรือไฟล์อันตราย
PhillipH

@PhillipH เขียนคำตอบสำหรับผู้ที่
wazz

คำตอบ:


83

ใน Urlmon.dll FindMimeFromDataมีฟังก์ชั่นที่เรียกว่า

จากเอกสารประกอบ

การตรวจจับชนิด MIME หรือ "data sniffing" หมายถึงกระบวนการพิจารณาประเภท MIME ที่เหมาะสมจากข้อมูลไบนารี ผลลัพธ์สุดท้ายขึ้นอยู่กับการรวมกันของส่วนหัวชนิด MIME ที่เซิร์ฟเวอร์ให้มานามสกุลไฟล์และ / หรือข้อมูลเอง โดยทั่วไปมีเพียง 256 ไบต์แรกของข้อมูลเท่านั้นที่มีความสำคัญ

ดังนั้นอ่านครั้งแรก (ถึง) 256 FindMimeFromDataไบต์จากไฟล์และผ่านมันไป


6
วิธีนี้น่าเชื่อถือแค่ไหน?
John Bubriski

22
ตามstackoverflow.com/questions/4833113/…ฟังก์ชั่นนั้นสามารถระบุได้เพียง 26 ประเภทเท่านั้นดังนั้นฉันไม่คิดว่ามันน่าเชื่อถือ เช่นไฟล์ '* .docx' ถูกกำหนดเป็น 'application / x-zip-compression'
พระคุณเจ้า

54
ฉันคิดว่าเป็นเพราะ docx เป็นไฟล์ zip อย่างเห็นได้ชัด
Nick Devereaux

27
Docx เป็นไฟล์ซิปแต่ mimetype สำหรับ. docx คือ "application / vnd.openxmlformats-officedocument.wordprocessingml.document" แม้ว่าสามารถตรวจสอบได้จากการตรวจสอบแบบไบนารีเท่านั้น แต่อาจไม่ใช่วิธีที่มีประสิทธิภาพที่สุดในการทำและในกรณีส่วนใหญ่คุณจะต้องอ่านมากกว่า 256 ไบต์แรก
BrainSlugs83

172

ฉันใช้ urlmon.dll ในท้ายที่สุด ฉันคิดว่าจะมีวิธีที่ง่ายกว่านี้ แต่ใช้งานได้ ฉันรวมรหัสเพื่อช่วยเหลือผู้อื่นและอนุญาตให้ฉันค้นหาอีกครั้งหากต้องการ

using System.Runtime.InteropServices;

...

    [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
    private extern static System.UInt32 FindMimeFromData(
        System.UInt32 pBC,
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl,
        [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
        System.UInt32 cbSize,
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed,
        System.UInt32 dwMimeFlags,
        out System.UInt32 ppwzMimeOut,
        System.UInt32 dwReserverd
    );

    public static string getMimeFromFile(string filename)
    {
        if (!File.Exists(filename))
            throw new FileNotFoundException(filename + " not found");

        byte[] buffer = new byte[256];
        using (FileStream fs = new FileStream(filename, FileMode.Open))
        {
            if (fs.Length >= 256)
                fs.Read(buffer, 0, 256);
            else
                fs.Read(buffer, 0, (int)fs.Length);
        }
        try
        {
            System.UInt32 mimetype;
            FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
            System.IntPtr mimeTypePtr = new IntPtr(mimetype);
            string mime = Marshal.PtrToStringUni(mimeTypePtr);
            Marshal.FreeCoTaskMem(mimeTypePtr);
            return mime;
        }
        catch (Exception e)
        {
            return "unknown/unknown";
        }
    }

3
อาจเป็นสิ่งที่แมปในรีจิสทรี
mkmurray


6
ฉันพบปัญหากับรหัสนี้เมื่อโฮสต์ไว้ใน IIS บน Windows 8 การใช้งานบน pinvoke.net (ซึ่งมีความแตกต่างเล็กน้อย) แก้ไขปัญหา: pinvoke.net/default.aspx/urlmon.findmimefromdata
Rohland

2
ฉันทดสอบโค้ดนี้กับ IIS 7 แล้วและไม่ได้ผลสำหรับฉัน ฉันมีไฟล์ CSV ที่ฉันกำลังทดสอบ ฉันเปลี่ยนนามสกุลของ CSV (เป็น. png, .jpeg ฯลฯ ) และการเปลี่ยนแปลงชนิด mime ด้วยนามสกุล (image / png, image / jpeg) ฉันอาจจะผิด แต่มันก็เป็นความเข้าใจของฉันที่ Urlmon.dll กำหนด mimetype โดยใช้ข้อมูลเมตาของไฟล์ไม่ใช่แค่เป็นส่วนขยาย
connorbode

2
ใช้งานไม่ได้กับแอป 64 บิตให้ดูที่นี่แทน: stackoverflow.com/questions/18358548//
omer schleifer

99

ฉันพบวิธีแก้ไขปัญหาแบบตายตัวฉันหวังว่าฉันจะช่วยคนอื่น:

public static class MIMEAssistant
{
  private static readonly Dictionary<string, string> MIMETypesDictionary = new Dictionary<string, string>
  {
    {"ai", "application/postscript"},
    {"aif", "audio/x-aiff"},
    {"aifc", "audio/x-aiff"},
    {"aiff", "audio/x-aiff"},
    {"asc", "text/plain"},
    {"atom", "application/atom+xml"},
    {"au", "audio/basic"},
    {"avi", "video/x-msvideo"},
    {"bcpio", "application/x-bcpio"},
    {"bin", "application/octet-stream"},
    {"bmp", "image/bmp"},
    {"cdf", "application/x-netcdf"},
    {"cgm", "image/cgm"},
    {"class", "application/octet-stream"},
    {"cpio", "application/x-cpio"},
    {"cpt", "application/mac-compactpro"},
    {"csh", "application/x-csh"},
    {"css", "text/css"},
    {"dcr", "application/x-director"},
    {"dif", "video/x-dv"},
    {"dir", "application/x-director"},
    {"djv", "image/vnd.djvu"},
    {"djvu", "image/vnd.djvu"},
    {"dll", "application/octet-stream"},
    {"dmg", "application/octet-stream"},
    {"dms", "application/octet-stream"},
    {"doc", "application/msword"},
    {"docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
    {"dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"},
    {"docm","application/vnd.ms-word.document.macroEnabled.12"},
    {"dotm","application/vnd.ms-word.template.macroEnabled.12"},
    {"dtd", "application/xml-dtd"},
    {"dv", "video/x-dv"},
    {"dvi", "application/x-dvi"},
    {"dxr", "application/x-director"},
    {"eps", "application/postscript"},
    {"etx", "text/x-setext"},
    {"exe", "application/octet-stream"},
    {"ez", "application/andrew-inset"},
    {"gif", "image/gif"},
    {"gram", "application/srgs"},
    {"grxml", "application/srgs+xml"},
    {"gtar", "application/x-gtar"},
    {"hdf", "application/x-hdf"},
    {"hqx", "application/mac-binhex40"},
    {"htm", "text/html"},
    {"html", "text/html"},
    {"ice", "x-conference/x-cooltalk"},
    {"ico", "image/x-icon"},
    {"ics", "text/calendar"},
    {"ief", "image/ief"},
    {"ifb", "text/calendar"},
    {"iges", "model/iges"},
    {"igs", "model/iges"},
    {"jnlp", "application/x-java-jnlp-file"},
    {"jp2", "image/jp2"},
    {"jpe", "image/jpeg"},
    {"jpeg", "image/jpeg"},
    {"jpg", "image/jpeg"},
    {"js", "application/x-javascript"},
    {"kar", "audio/midi"},
    {"latex", "application/x-latex"},
    {"lha", "application/octet-stream"},
    {"lzh", "application/octet-stream"},
    {"m3u", "audio/x-mpegurl"},
    {"m4a", "audio/mp4a-latm"},
    {"m4b", "audio/mp4a-latm"},
    {"m4p", "audio/mp4a-latm"},
    {"m4u", "video/vnd.mpegurl"},
    {"m4v", "video/x-m4v"},
    {"mac", "image/x-macpaint"},
    {"man", "application/x-troff-man"},
    {"mathml", "application/mathml+xml"},
    {"me", "application/x-troff-me"},
    {"mesh", "model/mesh"},
    {"mid", "audio/midi"},
    {"midi", "audio/midi"},
    {"mif", "application/vnd.mif"},
    {"mov", "video/quicktime"},
    {"movie", "video/x-sgi-movie"},
    {"mp2", "audio/mpeg"},
    {"mp3", "audio/mpeg"},
    {"mp4", "video/mp4"},
    {"mpe", "video/mpeg"},
    {"mpeg", "video/mpeg"},
    {"mpg", "video/mpeg"},
    {"mpga", "audio/mpeg"},
    {"ms", "application/x-troff-ms"},
    {"msh", "model/mesh"},
    {"mxu", "video/vnd.mpegurl"},
    {"nc", "application/x-netcdf"},
    {"oda", "application/oda"},
    {"ogg", "application/ogg"},
    {"pbm", "image/x-portable-bitmap"},
    {"pct", "image/pict"},
    {"pdb", "chemical/x-pdb"},
    {"pdf", "application/pdf"},
    {"pgm", "image/x-portable-graymap"},
    {"pgn", "application/x-chess-pgn"},
    {"pic", "image/pict"},
    {"pict", "image/pict"},
    {"png", "image/png"}, 
    {"pnm", "image/x-portable-anymap"},
    {"pnt", "image/x-macpaint"},
    {"pntg", "image/x-macpaint"},
    {"ppm", "image/x-portable-pixmap"},
    {"ppt", "application/vnd.ms-powerpoint"},
    {"pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation"},
    {"potx","application/vnd.openxmlformats-officedocument.presentationml.template"},
    {"ppsx","application/vnd.openxmlformats-officedocument.presentationml.slideshow"},
    {"ppam","application/vnd.ms-powerpoint.addin.macroEnabled.12"},
    {"pptm","application/vnd.ms-powerpoint.presentation.macroEnabled.12"},
    {"potm","application/vnd.ms-powerpoint.template.macroEnabled.12"},
    {"ppsm","application/vnd.ms-powerpoint.slideshow.macroEnabled.12"},
    {"ps", "application/postscript"},
    {"qt", "video/quicktime"},
    {"qti", "image/x-quicktime"},
    {"qtif", "image/x-quicktime"},
    {"ra", "audio/x-pn-realaudio"},
    {"ram", "audio/x-pn-realaudio"},
    {"ras", "image/x-cmu-raster"},
    {"rdf", "application/rdf+xml"},
    {"rgb", "image/x-rgb"},
    {"rm", "application/vnd.rn-realmedia"},
    {"roff", "application/x-troff"},
    {"rtf", "text/rtf"},
    {"rtx", "text/richtext"},
    {"sgm", "text/sgml"},
    {"sgml", "text/sgml"},
    {"sh", "application/x-sh"},
    {"shar", "application/x-shar"},
    {"silo", "model/mesh"},
    {"sit", "application/x-stuffit"},
    {"skd", "application/x-koan"},
    {"skm", "application/x-koan"},
    {"skp", "application/x-koan"},
    {"skt", "application/x-koan"},
    {"smi", "application/smil"},
    {"smil", "application/smil"},
    {"snd", "audio/basic"},
    {"so", "application/octet-stream"},
    {"spl", "application/x-futuresplash"},
    {"src", "application/x-wais-source"},
    {"sv4cpio", "application/x-sv4cpio"},
    {"sv4crc", "application/x-sv4crc"},
    {"svg", "image/svg+xml"},
    {"swf", "application/x-shockwave-flash"},
    {"t", "application/x-troff"},
    {"tar", "application/x-tar"},
    {"tcl", "application/x-tcl"},
    {"tex", "application/x-tex"},
    {"texi", "application/x-texinfo"},
    {"texinfo", "application/x-texinfo"},
    {"tif", "image/tiff"},
    {"tiff", "image/tiff"},
    {"tr", "application/x-troff"},
    {"tsv", "text/tab-separated-values"},
    {"txt", "text/plain"},
    {"ustar", "application/x-ustar"},
    {"vcd", "application/x-cdlink"},
    {"vrml", "model/vrml"},
    {"vxml", "application/voicexml+xml"},
    {"wav", "audio/x-wav"},
    {"wbmp", "image/vnd.wap.wbmp"},
    {"wbmxl", "application/vnd.wap.wbxml"},
    {"wml", "text/vnd.wap.wml"},
    {"wmlc", "application/vnd.wap.wmlc"},
    {"wmls", "text/vnd.wap.wmlscript"},
    {"wmlsc", "application/vnd.wap.wmlscriptc"},
    {"wrl", "model/vrml"},
    {"xbm", "image/x-xbitmap"},
    {"xht", "application/xhtml+xml"},
    {"xhtml", "application/xhtml+xml"},
    {"xls", "application/vnd.ms-excel"},                        
    {"xml", "application/xml"},
    {"xpm", "image/x-xpixmap"},
    {"xsl", "application/xml"},
    {"xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
    {"xltx","application/vnd.openxmlformats-officedocument.spreadsheetml.template"},
    {"xlsm","application/vnd.ms-excel.sheet.macroEnabled.12"},
    {"xltm","application/vnd.ms-excel.template.macroEnabled.12"},
    {"xlam","application/vnd.ms-excel.addin.macroEnabled.12"},
    {"xlsb","application/vnd.ms-excel.sheet.binary.macroEnabled.12"},
    {"xslt", "application/xslt+xml"},
    {"xul", "application/vnd.mozilla.xul+xml"},
    {"xwd", "image/x-xwindowdump"},
    {"xyz", "chemical/x-xyz"},
    {"zip", "application/zip"}
  };

  public static string GetMIMEType(string fileName)
  {
    //get file extension
    string extension = Path.GetExtension(fileName).ToLowerInvariant();

    if (extension.Length > 0 && 
        MIMETypesDictionary.ContainsKey(extension.Remove(0, 1)))
    {
      return MIMETypesDictionary[extension.Remove(0, 1)];
    }
    return "unknown/unknown";
  }
}

58
สิ่งนี้ขึ้นอยู่กับชื่อไฟล์อย่างไรก็ตาม มันอาจจะมีประโยชน์สำหรับใครบางคนไม่ใช่ OP ที่ต้องการให้ทำโดยเนื้อหาไฟล์
mandreko

4
เซ็ตย่อยของรายการนี้ยังสะดวกสำหรับการแม็พ WebImage.ImageFormat กลับไปเป็นชนิด mime ขอบคุณ!
ปั้นจั่น

8
ขึ้นอยู่กับเป้าหมายของคุณคุณอาจต้องการส่งคืน "application / octet-stream" แทน "unknown / unknown"
Nicolas Raoul

4
เนื่องจากการแก้ไขของฉันถูกปฏิเสธฉันจะโพสต์ที่นี่: ส่วนขยายจะต้องเป็นตัวพิมพ์เล็กทั้งหมดไม่เช่นนั้นจะไม่พบในพจนานุกรม
Howie

3
@ JalalAldeenSaa'd - การแก้ไข IMHO ที่ดียิ่งขึ้นจะใช้StringComparer.OrdinalIgnoreCaseกับตัวสร้างพจนานุกรม การเปรียบเทียบลำดับนั้นเร็วกว่าค่าคงที่และคุณจะกำจัด.ToLower()และรูปแบบต่างๆ
Ivaylo Slavov

87

แก้ไข: เพียงใช้Mime Detective

ฉันใช้ลำดับไบต์อาร์เรย์เพื่อกำหนดประเภท MIME ที่ถูกต้องของไฟล์ที่กำหนด ข้อดีของการทำเช่นนี้เพียงแค่ดูที่นามสกุลไฟล์ของชื่อไฟล์คือหากผู้ใช้เปลี่ยนชื่อไฟล์เพื่อข้ามข้อ จำกัด การอัปโหลดไฟล์บางประเภทส่วนขยายของชื่อไฟล์จะไม่สามารถตรวจจับได้ ในทางกลับกันการรับลายเซ็นไฟล์ผ่านทางอาร์เรย์ไบต์จะหยุดพฤติกรรมซุกซนนี้

นี่คือตัวอย่างใน C #:

public class MimeType
{
    private static readonly byte[] BMP = { 66, 77 };
    private static readonly byte[] DOC = { 208, 207, 17, 224, 161, 177, 26, 225 };
    private static readonly byte[] EXE_DLL = { 77, 90 };
    private static readonly byte[] GIF = { 71, 73, 70, 56 };
    private static readonly byte[] ICO = { 0, 0, 1, 0 };
    private static readonly byte[] JPG = { 255, 216, 255 };
    private static readonly byte[] MP3 = { 255, 251, 48 };
    private static readonly byte[] OGG = { 79, 103, 103, 83, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 };
    private static readonly byte[] PDF = { 37, 80, 68, 70, 45, 49, 46 };
    private static readonly byte[] PNG = { 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82 };
    private static readonly byte[] RAR = { 82, 97, 114, 33, 26, 7, 0 };
    private static readonly byte[] SWF = { 70, 87, 83 };
    private static readonly byte[] TIFF = { 73, 73, 42, 0 };
    private static readonly byte[] TORRENT = { 100, 56, 58, 97, 110, 110, 111, 117, 110, 99, 101 };
    private static readonly byte[] TTF = { 0, 1, 0, 0, 0 };
    private static readonly byte[] WAV_AVI = { 82, 73, 70, 70 };
    private static readonly byte[] WMV_WMA = { 48, 38, 178, 117, 142, 102, 207, 17, 166, 217, 0, 170, 0, 98, 206, 108 };
    private static readonly byte[] ZIP_DOCX = { 80, 75, 3, 4 };

    public static string GetMimeType(byte[] file, string fileName)
    {

        string mime = "application/octet-stream"; //DEFAULT UNKNOWN MIME TYPE

        //Ensure that the filename isn't empty or null
        if (string.IsNullOrWhiteSpace(fileName))
        {
            return mime;
        }

        //Get the file extension
        string extension = Path.GetExtension(fileName) == null
                               ? string.Empty
                               : Path.GetExtension(fileName).ToUpper();

        //Get the MIME Type
        if (file.Take(2).SequenceEqual(BMP))
        {
            mime = "image/bmp";
        }
        else if (file.Take(8).SequenceEqual(DOC))
        {
            mime = "application/msword";
        }
        else if (file.Take(2).SequenceEqual(EXE_DLL))
        {
            mime = "application/x-msdownload"; //both use same mime type
        }
        else if (file.Take(4).SequenceEqual(GIF))
        {
            mime = "image/gif";
        }
        else if (file.Take(4).SequenceEqual(ICO))
        {
            mime = "image/x-icon";
        }
        else if (file.Take(3).SequenceEqual(JPG))
        {
            mime = "image/jpeg";
        }
        else if (file.Take(3).SequenceEqual(MP3))
        {
            mime = "audio/mpeg";
        }
        else if (file.Take(14).SequenceEqual(OGG))
        {
            if (extension == ".OGX")
            {
                mime = "application/ogg";
            }
            else if (extension == ".OGA")
            {
                mime = "audio/ogg";
            }
            else
            {
                mime = "video/ogg";
            }
        }
        else if (file.Take(7).SequenceEqual(PDF))
        {
            mime = "application/pdf";
        }
        else if (file.Take(16).SequenceEqual(PNG))
        {
            mime = "image/png";
        }
        else if (file.Take(7).SequenceEqual(RAR))
        {
            mime = "application/x-rar-compressed";
        }
        else if (file.Take(3).SequenceEqual(SWF))
        {
            mime = "application/x-shockwave-flash";
        }
        else if (file.Take(4).SequenceEqual(TIFF))
        {
            mime = "image/tiff";
        }
        else if (file.Take(11).SequenceEqual(TORRENT))
        {
            mime = "application/x-bittorrent";
        }
        else if (file.Take(5).SequenceEqual(TTF))
        {
            mime = "application/x-font-ttf";
        }
        else if (file.Take(4).SequenceEqual(WAV_AVI))
        {
            mime = extension == ".AVI" ? "video/x-msvideo" : "audio/x-wav";
        }
        else if (file.Take(16).SequenceEqual(WMV_WMA))
        {
            mime = extension == ".WMA" ? "audio/x-ms-wma" : "video/x-ms-wmv";
        }
        else if (file.Take(4).SequenceEqual(ZIP_DOCX))
        {
            mime = extension == ".DOCX" ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "application/x-zip-compressed";
        }

        return mime;
    }


}

แจ้งให้ทราบล่วงหน้าฉันจัดการประเภทไฟล์ DOCX แตกต่างกันเนื่องจาก DOCX เป็นเพียงไฟล์ ZIP ในสถานการณ์นี้ฉันเพียงตรวจสอบนามสกุลไฟล์เมื่อฉันตรวจสอบว่ามีลำดับนั้น ตัวอย่างนี้ยังไม่สมบูรณ์สำหรับบางคน แต่คุณสามารถเพิ่มของคุณเองได้อย่างง่ายดาย

หากคุณต้องการที่จะเพิ่มชนิด MIME มากขึ้นคุณจะได้รับลำดับไบต์อาร์เรย์ของหลายประเภทไฟล์ที่แตกต่างจากที่นี่ นอกจากนี้นี่เป็นอีกแหล่งข้อมูลที่ดีเกี่ยวกับลายเซ็นไฟล์

สิ่งที่ฉันทำบ่อยครั้งถ้าสิ่งที่ล้มเหลวคือขั้นตอนผ่านไฟล์หลาย ๆ ประเภทที่ฉันกำลังมองหาและค้นหารูปแบบตามลำดับไบต์ของไฟล์ ในท้ายที่สุดนี่เป็นการยืนยันพื้นฐานและไม่สามารถใช้สำหรับการพิสูจน์ 100% ของการกำหนดประเภทไฟล์


1
ขอบคุณ @ROFLwTIME - ฉันได้ปรับปรุงสิ่งนี้เล็กน้อยเพื่อจัดการเมื่อเรามีอาร์เรย์ไบต์ แต่ไม่มีชื่อไฟล์ / นามสกุล (แน่นอนว่าสำหรับ mime บางประเภทจะต้องมีค่าเริ่มต้นหรือจำเป็นต้องได้รับการปรับปรุงเพิ่มเติมเพื่อระบุอย่างถูกต้อง) แต่ถ้าใครต้องการให้ฉันโพสต์รหัสโปรดแจ้งให้เราทราบ
Chris

+1 สำหรับการใช้ไบต์ ตอนนี้เราสามารถรับจำนวนไบต์ที่คาดไว้สำหรับชนิด mime เฉพาะเพื่อทดสอบ (ไม่ใช่ค่าเริ่มต้นของ 256) อย่างไรก็ตามฉันจะไปที่ struct ที่นี่พร้อมด้วยส่วนขยายไบต์และ mime / type เป็นคุณสมบัติและอาจเก็บพจนานุกรมของโครงสร้างที่กำหนดไว้ล่วงหน้า สิ่งนี้จะช่วยฉันได้ไม่รู้จบหากเช็คอื่น
Ivaylo Slavov

2
ปัญหาเกี่ยวกับวิธีการนี้คือตัวอย่างเช่นไฟล์ข้อความที่ขึ้นต้นด้วย "MZ" จะถูกตีความว่าเป็นไฟล์. EXE กล่าวอีกนัยหนึ่งคุณควรพิจารณาการขยายอย่างน้อยทุกกรณีรวมทั้งลายเซ็นที่ยาวขึ้นหรือฮิวริสติกต่อรูปแบบเพื่อหลีกเลี่ยงผลบวกปลอม
NéstorSánchez A.

1
@Nutshell ฉันเชื่อว่า XLS มี 0 ไบต์ในขณะที่ DOC ไม่มีดังนั้นให้ตรวจสอบ XLS ก่อนแล้วตามด้วย DOC สำหรับ XLSX / DOCX พวกเขาแบ่งปันลายเซ็นเดียวกัน (ZIP) ดังนั้นเพื่อแยกความแตกต่างที่คุณจะต้องลึกกว่าการอ่านส่วนหัว ตัวอย่างเช่นไฟล์ XLSX มีสตริง "xl / _rels / workbook.xml.rels" ใกล้ส่วนหัวในขณะที่ไฟล์ DOCX มีสตริง "word / _rels / document.xml.rels" ใกล้ส่วนหัว นี่เป็นเพียงหนึ่งในหลาย ๆ วิธีในการลองและแยกแยะประเภทเหล่านั้นและแน่นอนว่าจะไม่ครอบคลุมสถานการณ์ 100% (เช่นไฟล์ซิปที่มีไฟล์ DOCX / XLSX อยู่)
ROFLwTIME

7
ไงพวก. ฉันเป็นคนหนึ่งที่แยกแยะ FileTypeDetective ดั้งเดิมกับ MimeDetective ที่ gitHub ฉันมีความสุขถ้ามันมีประโยชน์ และฉันได้พูดคุยกับนักพัฒนาเทรลแม็กซ์ เราได้เปลี่ยนใบอนุญาตเป็น MIT!
Muraad Nofal

36

หากคุณกำลังใช้. NET Framework 4.5 หรือสูงกว่าตอนนี้มีวิธีการ MimeMapping.GetMimeMapping (ชื่อไฟล์) ที่จะส่งคืนสตริงด้วยการจับคู่ Mime ที่ถูกต้องสำหรับชื่อไฟล์ที่ส่งผ่าน โปรดทราบว่านี่ใช้นามสกุลไฟล์ไม่ใช่ข้อมูลในไฟล์เอง

เอกสารอยู่ที่http://msdn.microsoft.com/en-us/library/system.web.mimemapping.getmimemapping


3
สิ่งนี้ใช้ได้กับฉันและใช้รหัสเพียงหนึ่งบรรทัด var mimetype = System.Web.MimeMapping.GetMimeMapping(<pathToFile>);
แกร์รี

50
สิ่งนี้ไม่ตอบคำถามเดิม "ถ้านามสกุลไฟล์ไม่ถูกต้องหรือหายไป" GetMimeMapping ใช้พจนานุกรมสแตติกของส่วนขยายและรายการ mime
Barry Hagan

1
ฉันพบชั้นนี้ถ้าเป็นประโยชน์อย่างมาก :)
TeYoU

1
ไม่มีใน. net-core คุณสามารถใช้: string contentType; ใหม่ FileExtensionContentTypeProvider () TryGetContentType (ชื่อไฟล์, out contentType); contentType = contentType ?? "application / octet สตรีม";
John Pankowicz

2
โดยปกติฉันไม่ลงคะแนนคำตอบ แต่เป็นคำตอบที่เข้าใจผิดนี้ฉันทำเช่นนั้น คำถามบอกว่าไม่เชื่อถือนามสกุลไฟล์
Anjani

26

คุณยังสามารถดูในรีจิสทรี

    using System.IO;
    using Microsoft.Win32;

    string GetMimeType(FileInfo fileInfo)
    {
        string mimeType = "application/unknown";

        RegistryKey regKey = Registry.ClassesRoot.OpenSubKey(
            fileInfo.Extension.ToLower()
            );

        if(regKey != null)
        {
            object contentType = regKey.GetValue("Content Type");

            if(contentType != null)
                mimeType = contentType.ToString();
        }

        return mimeType;
    }

ไม่ทางใดก็ทางหนึ่งคุณจะต้องแตะลงในฐานข้อมูลของ MIME ไม่ว่าจะถูกแมปจากส่วนขยายหรือหมายเลขเวทย์มนตร์นั้นเป็นเรื่องเล็กน้อย - การลงทะเบียน windows เป็นหนึ่งในสถานที่ดังกล่าว สำหรับโซลูชันที่ไม่ขึ้นกับแพลตฟอร์มแม้ว่าจะต้องใช้ฐานข้อมูลนี้ในการส่งรหัส (หรือเป็นไลบรารีแบบสแตนด์อโลน)


1
@ Rabbi ถึงแม้ว่าคำถามจะเจาะจงไปที่เนื้อหาของไฟล์และไม่ใช่ส่วนขยายคำตอบนี้อาจเป็นประโยชน์กับคนอื่น ๆ (เช่นตัวฉัน) ที่กำลังผ่าน แม้ว่าคำตอบเช่นนี้จะไม่ได้รับการยอมรับ แต่ก็ยังดีที่มีข้อมูล
BrainSlugs83

5
สิ่งนี้ไม่เพียงแค่รับค่า mime ตามนามสกุลของชื่อไฟล์หรือไม่? เกิดอะไรขึ้นถ้าไฟล์เป็น. docx และตัวตลกบางคนตัดสินใจเปลี่ยนชื่อเป็น. doc คุณได้ประเภท mime ที่ผิดแน่นอน
kolin

8
@ kolin คุณพูดถูก แต่ก็เป็นคำพูดที่ว่า "ทำให้มันเป็นหลักฐานที่งี่เง่าและใครบางคนจะทำให้คนโง่ขึ้น" :)
Serguei

เมื่อทำงานกับบทบาท Windows Azure Web หรือโฮสต์อื่น ๆ ที่รันแอพของคุณใน Limited Trust - อย่าลืมว่าคุณจะไม่ได้รับอนุญาตให้เข้าถึงรีจิสตรี การรวมกันของ try-for-for-registry และพจนานุกรมในหน่วยความจำเช่นคำตอบของ Anykey ดูเหมือนเป็นทางออกที่ดีที่มีทั้งคู่
Ognyan Dimitrov

8

ฉันใช้โซลูชันไฮบริด:

    using System.Runtime.InteropServices;

    [DllImport (@"urlmon.dll", CharSet = CharSet.Auto)]
    private extern static System.UInt32 FindMimeFromData(
        System.UInt32 pBC, 
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl,
        [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
        System.UInt32 cbSize,
        [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed,
        System.UInt32 dwMimeFlags,
        out System.UInt32 ppwzMimeOut,
        System.UInt32 dwReserverd
    );

    private string GetMimeFromRegistry (string Filename)
    {
        string mime = "application/octetstream";
        string ext = System.IO.Path.GetExtension(Filename).ToLower();
        Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
        if (rk != null && rk.GetValue("Content Type") != null)
            mime = rk.GetValue("Content Type").ToString();
        return mime;
    }

    public string GetMimeTypeFromFileAndRegistry (string filename)
    {
        if (!File.Exists(filename))
        {
           return GetMimeFromRegistry (filename);
        }

        byte[] buffer = new byte[256];

        using (FileStream fs = new FileStream(filename, FileMode.Open))
        {
            if (fs.Length >= 256)
                fs.Read(buffer, 0, 256);
            else
                fs.Read(buffer, 0, (int)fs.Length);
        }

        try
        {            
            System.UInt32 mimetype;

            FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);

            System.IntPtr mimeTypePtr = new IntPtr(mimetype);

            string mime = Marshal.PtrToStringUni(mimeTypePtr);

            Marshal.FreeCoTaskMem(mimeTypePtr);

            if (string.IsNullOrWhiteSpace (mime) || 
                mime =="text/plain" || mime == "application/octet-stream")                    
            {
                return GetMimeFromRegistry (filename);
            }

            return mime;
        }
        catch (Exception e)
        {
            return GetMimeFromRegistry (filename);
        }
    }

1
ขอบคุณสำหรับรหัส มันทำงานได้บางส่วน สำหรับทั้งไฟล์ "doc" และ "tif" จะส่งคืน "application / octet-stream" มีตัวเลือกอื่น ๆ ที่ใช้ได้
ชาห์

มันจะเป็นการดีที่จะเห็นโซลูชันไฮบริดของพจนานุกรมส่วนขยายและ urlmon ด้านบน
BrainSlugs83

@PranavShah โปรดทราบว่าความรู้ของเซิร์ฟเวอร์เกี่ยวกับ mime-types (ที่ถูกส่งคืนโดยการค้นหารีจิสตรี) จะขึ้นอยู่กับซอฟต์แวร์ที่ติดตั้งบนเซิร์ฟเวอร์ การติดตั้ง windows พื้นฐานหรือเว็บเซิร์ฟเวอร์เฉพาะไม่น่าเชื่อถือที่จะรู้ว่าซอฟต์แวร์ประเภทบุคคลที่สามประเภท mime ที่ไม่ได้ติดตั้งอย่างจำเป็น ถึงกระนั้นก็ควรรู้ว่า.docไฟล์คืออะไร
Ivaylo Slavov

6

HeyRed.Mime.MimeGuesser.GuessMimeType จาก Nuget จะเป็นทางออกที่ดีที่สุดหากคุณต้องการโฮสต์โซลูชัน ASP.NET ของคุณในสภาพแวดล้อมที่ไม่ใช่หน้าต่าง

การแมปนามสกุลไฟล์ไม่ปลอดภัยมาก หากผู้โจมตีจะอัปโหลดส่วนขยายที่ไม่ถูกต้องพจนานุกรมการจับคู่จะอนุญาตให้มีการแจกจ่ายไฟล์เอ็กซีคิวต์ภายในไฟล์. jpg ดังนั้นให้ใช้ไลบรารีการสูดดมเนื้อหาเพื่อทราบประเภทเนื้อหาจริง

 public  static string MimeTypeFrom(byte[] dataBytes, string fileName)
 {
        var contentType = HeyRed.Mime.MimeGuesser.GuessMimeType(dataBytes);
        if (string.IsNullOrEmpty(contentType))
        {
            return HeyRed.Mime.MimeTypesMap.GetMimeType(fileName);
        }
  return contentType;

1
จนถึงตอนนี้ห้องสมุดที่ดีที่สุดที่ฉันได้ลอง พบประเภทเนื้อหาของไฟล์ทุกไฟล์ที่ฉันใส่ไว้ในโฟลเดอร์ + .net สนับสนุนหลัก!
TS

3

ฉันคิดว่าคำตอบที่ถูกต้องคือการรวมกันระหว่างคำตอบของสตีฟมอร์แกนและคำตอบของเซร์กี นั่นคือวิธีที่ Internet Explorer ทำ การเรียก pinvoke เพื่อใช้FindMimeFromDataงานสำหรับ mime ประเภทรหัสตายยากเพียง 26 ประเภท นอกจากนี้มันจะให้ประเภท mime ที่คลุมเครือ (เช่นtext/plainหรือapplication/octet-stream) แม้ว่าอาจมีชนิดของ mime ที่เฉพาะเจาะจงและเหมาะสมกว่า หากไม่สามารถให้ประเภท mime ได้คุณสามารถไปที่รีจิสตรีเพื่อรับประเภท mime ที่เฉพาะเจาะจงมากขึ้น รีจิสตรีเซิร์ฟเวอร์อาจมีประเภท mime ที่ทันสมัยมากขึ้น

อ้างถึง: http://msdn.microsoft.com/en-us/library/ms775147(VS.85).aspx


3

คลาสนี้ใช้คำตอบก่อนหน้านี้เพื่อลองด้วย 3 วิธีแตกต่างกัน: harcoded ตามนามสกุล, FindMimeFromData API และการใช้รีจิสตรี

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;

using Microsoft.Win32;

namespace YourNamespace
{
    public static class MimeTypeParser
    {
        [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
        private extern static System.UInt32 FindMimeFromData(
                System.UInt32 pBC,
                [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl,
                [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
                System.UInt32 cbSize,
                [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed,
                System.UInt32 dwMimeFlags,
                out System.UInt32 ppwzMimeOut,
                System.UInt32 dwReserverd
        );

        public static string GetMimeType(string sFilePath)
        {
            string sMimeType = GetMimeTypeFromList(sFilePath);

            if (String.IsNullOrEmpty(sMimeType))
            {
                sMimeType = GetMimeTypeFromFile(sFilePath);

                if (String.IsNullOrEmpty(sMimeType))
                {
                    sMimeType = GetMimeTypeFromRegistry(sFilePath);
                }
            }

            return sMimeType;
        }

        public static string GetMimeTypeFromList(string sFileNameOrPath)
        {
            string sMimeType = null;
            string sExtensionWithoutDot = Path.GetExtension(sFileNameOrPath).Substring(1).ToLower();

            if (!String.IsNullOrEmpty(sExtensionWithoutDot) && spDicMIMETypes.ContainsKey(sExtensionWithoutDot))
            {
                sMimeType = spDicMIMETypes[sExtensionWithoutDot];
            }

            return sMimeType;
        }

        public static string GetMimeTypeFromRegistry(string sFileNameOrPath)
        {
            string sMimeType = null;
            string sExtension = Path.GetExtension(sFileNameOrPath).ToLower();
            RegistryKey pKey = Registry.ClassesRoot.OpenSubKey(sExtension);

            if (pKey != null && pKey.GetValue("Content Type") != null)
            {
                sMimeType = pKey.GetValue("Content Type").ToString();
            }

            return sMimeType;
        }

        public static string GetMimeTypeFromFile(string sFilePath)
        {
            string sMimeType = null;

            if (File.Exists(sFilePath))
            {
                byte[] abytBuffer = new byte[256];

                using (FileStream pFileStream = new FileStream(sFilePath, FileMode.Open))
                {
                    if (pFileStream.Length >= 256)
                    {
                        pFileStream.Read(abytBuffer, 0, 256);
                    }
                    else
                    {
                        pFileStream.Read(abytBuffer, 0, (int)pFileStream.Length);
                    }
                }

                try
                {
                    UInt32 unMimeType;

                    FindMimeFromData(0, null, abytBuffer, 256, null, 0, out unMimeType, 0);

                    IntPtr pMimeType = new IntPtr(unMimeType);
                    string sMimeTypeFromFile = Marshal.PtrToStringUni(pMimeType);

                    Marshal.FreeCoTaskMem(pMimeType);

                    if (!String.IsNullOrEmpty(sMimeTypeFromFile) && sMimeTypeFromFile != "text/plain" && sMimeTypeFromFile != "application/octet-stream")
                    {
                        sMimeType = sMimeTypeFromFile;
                    }
                }
                catch {}
            }

            return sMimeType;
        }

        private static readonly Dictionary<string, string> spDicMIMETypes = new Dictionary<string, string>
        {
            {"ai", "application/postscript"},
            {"aif", "audio/x-aiff"},
            {"aifc", "audio/x-aiff"},
            {"aiff", "audio/x-aiff"},
            {"asc", "text/plain"},
            {"atom", "application/atom+xml"},
            {"au", "audio/basic"},
            {"avi", "video/x-msvideo"},
            {"bcpio", "application/x-bcpio"},
            {"bin", "application/octet-stream"},
            {"bmp", "image/bmp"},
            {"cdf", "application/x-netcdf"},
            {"cgm", "image/cgm"},
            {"class", "application/octet-stream"},
            {"cpio", "application/x-cpio"},
            {"cpt", "application/mac-compactpro"},
            {"csh", "application/x-csh"},
            {"css", "text/css"},
            {"dcr", "application/x-director"},
            {"dif", "video/x-dv"},
            {"dir", "application/x-director"},
            {"djv", "image/vnd.djvu"},
            {"djvu", "image/vnd.djvu"},
            {"dll", "application/octet-stream"},
            {"dmg", "application/octet-stream"},
            {"dms", "application/octet-stream"},
            {"doc", "application/msword"},
            {"docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
            {"dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"},
            {"docm","application/vnd.ms-word.document.macroEnabled.12"},
            {"dotm","application/vnd.ms-word.template.macroEnabled.12"},
            {"dtd", "application/xml-dtd"},
            {"dv", "video/x-dv"},
            {"dvi", "application/x-dvi"},
            {"dxr", "application/x-director"},
            {"eps", "application/postscript"},
            {"etx", "text/x-setext"},
            {"exe", "application/octet-stream"},
            {"ez", "application/andrew-inset"},
            {"gif", "image/gif"},
            {"gram", "application/srgs"},
            {"grxml", "application/srgs+xml"},
            {"gtar", "application/x-gtar"},
            {"hdf", "application/x-hdf"},
            {"hqx", "application/mac-binhex40"},
            {"htc", "text/x-component"},
            {"htm", "text/html"},
            {"html", "text/html"},
            {"ice", "x-conference/x-cooltalk"},
            {"ico", "image/x-icon"},
            {"ics", "text/calendar"},
            {"ief", "image/ief"},
            {"ifb", "text/calendar"},
            {"iges", "model/iges"},
            {"igs", "model/iges"},
            {"jnlp", "application/x-java-jnlp-file"},
            {"jp2", "image/jp2"},
            {"jpe", "image/jpeg"},
            {"jpeg", "image/jpeg"},
            {"jpg", "image/jpeg"},
            {"js", "application/x-javascript"},
            {"kar", "audio/midi"},
            {"latex", "application/x-latex"},
            {"lha", "application/octet-stream"},
            {"lzh", "application/octet-stream"},
            {"m3u", "audio/x-mpegurl"},
            {"m4a", "audio/mp4a-latm"},
            {"m4b", "audio/mp4a-latm"},
            {"m4p", "audio/mp4a-latm"},
            {"m4u", "video/vnd.mpegurl"},
            {"m4v", "video/x-m4v"},
            {"mac", "image/x-macpaint"},
            {"man", "application/x-troff-man"},
            {"mathml", "application/mathml+xml"},
            {"me", "application/x-troff-me"},
            {"mesh", "model/mesh"},
            {"mid", "audio/midi"},
            {"midi", "audio/midi"},
            {"mif", "application/vnd.mif"},
            {"mov", "video/quicktime"},
            {"movie", "video/x-sgi-movie"},
            {"mp2", "audio/mpeg"},
            {"mp3", "audio/mpeg"},
            {"mp4", "video/mp4"},
            {"mpe", "video/mpeg"},
            {"mpeg", "video/mpeg"},
            {"mpg", "video/mpeg"},
            {"mpga", "audio/mpeg"},
            {"ms", "application/x-troff-ms"},
            {"msh", "model/mesh"},
            {"mxu", "video/vnd.mpegurl"},
            {"nc", "application/x-netcdf"},
            {"oda", "application/oda"},
            {"ogg", "application/ogg"},
            {"pbm", "image/x-portable-bitmap"},
            {"pct", "image/pict"},
            {"pdb", "chemical/x-pdb"},
            {"pdf", "application/pdf"},
            {"pgm", "image/x-portable-graymap"},
            {"pgn", "application/x-chess-pgn"},
            {"pic", "image/pict"},
            {"pict", "image/pict"},
            {"png", "image/png"}, 
            {"pnm", "image/x-portable-anymap"},
            {"pnt", "image/x-macpaint"},
            {"pntg", "image/x-macpaint"},
            {"ppm", "image/x-portable-pixmap"},
            {"ppt", "application/vnd.ms-powerpoint"},
            {"pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation"},
            {"potx","application/vnd.openxmlformats-officedocument.presentationml.template"},
            {"ppsx","application/vnd.openxmlformats-officedocument.presentationml.slideshow"},
            {"ppam","application/vnd.ms-powerpoint.addin.macroEnabled.12"},
            {"pptm","application/vnd.ms-powerpoint.presentation.macroEnabled.12"},
            {"potm","application/vnd.ms-powerpoint.template.macroEnabled.12"},
            {"ppsm","application/vnd.ms-powerpoint.slideshow.macroEnabled.12"},
            {"ps", "application/postscript"},
            {"qt", "video/quicktime"},
            {"qti", "image/x-quicktime"},
            {"qtif", "image/x-quicktime"},
            {"ra", "audio/x-pn-realaudio"},
            {"ram", "audio/x-pn-realaudio"},
            {"ras", "image/x-cmu-raster"},
            {"rdf", "application/rdf+xml"},
            {"rgb", "image/x-rgb"},
            {"rm", "application/vnd.rn-realmedia"},
            {"roff", "application/x-troff"},
            {"rtf", "text/rtf"},
            {"rtx", "text/richtext"},
            {"sgm", "text/sgml"},
            {"sgml", "text/sgml"},
            {"sh", "application/x-sh"},
            {"shar", "application/x-shar"},
            {"silo", "model/mesh"},
            {"sit", "application/x-stuffit"},
            {"skd", "application/x-koan"},
            {"skm", "application/x-koan"},
            {"skp", "application/x-koan"},
            {"skt", "application/x-koan"},
            {"smi", "application/smil"},
            {"smil", "application/smil"},
            {"snd", "audio/basic"},
            {"so", "application/octet-stream"},
            {"spl", "application/x-futuresplash"},
            {"src", "application/x-wais-source"},
            {"sv4cpio", "application/x-sv4cpio"},
            {"sv4crc", "application/x-sv4crc"},
            {"svg", "image/svg+xml"},
            {"swf", "application/x-shockwave-flash"},
            {"t", "application/x-troff"},
            {"tar", "application/x-tar"},
            {"tcl", "application/x-tcl"},
            {"tex", "application/x-tex"},
            {"texi", "application/x-texinfo"},
            {"texinfo", "application/x-texinfo"},
            {"tif", "image/tiff"},
            {"tiff", "image/tiff"},
            {"tr", "application/x-troff"},
            {"tsv", "text/tab-separated-values"},
            {"txt", "text/plain"},
            {"ustar", "application/x-ustar"},
            {"vcd", "application/x-cdlink"},
            {"vrml", "model/vrml"},
            {"vxml", "application/voicexml+xml"},
            {"wav", "audio/x-wav"},
            {"wbmp", "image/vnd.wap.wbmp"},
            {"wbmxl", "application/vnd.wap.wbxml"},
            {"wml", "text/vnd.wap.wml"},
            {"wmlc", "application/vnd.wap.wmlc"},
            {"wmls", "text/vnd.wap.wmlscript"},
            {"wmlsc", "application/vnd.wap.wmlscriptc"},
            {"wrl", "model/vrml"},
            {"xbm", "image/x-xbitmap"},
            {"xht", "application/xhtml+xml"},
            {"xhtml", "application/xhtml+xml"},
            {"xls", "application/vnd.ms-excel"},                                                
            {"xml", "application/xml"},
            {"xpm", "image/x-xpixmap"},
            {"xsl", "application/xml"},
            {"xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
            {"xltx","application/vnd.openxmlformats-officedocument.spreadsheetml.template"},
            {"xlsm","application/vnd.ms-excel.sheet.macroEnabled.12"},
            {"xltm","application/vnd.ms-excel.template.macroEnabled.12"},
            {"xlam","application/vnd.ms-excel.addin.macroEnabled.12"},
            {"xlsb","application/vnd.ms-excel.sheet.binary.macroEnabled.12"},
            {"xslt", "application/xslt+xml"},
            {"xul", "application/vnd.mozilla.xul+xml"},
            {"xwd", "image/x-xwindowdump"},
            {"xyz", "chemical/x-xyz"},
            {"zip", "application/zip"}
        };
    }
}

3
อย่าลืมลองจับตาดูรีจิสทรี - คุณจะไม่ได้รับอนุญาตให้เข้าถึงในโหมด จำกัด ซึ่งเป็นกรณีที่มีบทบาทของ Azure Web ในความไว้วางใจที่ จำกัด หรือโฮสต์อื่น ๆ ที่มีความน่าเชื่อถือ จำกัด
Ognyan Dimitrov

2

ฉันพบว่าสิ่งนี้มีประโยชน์ สำหรับนักพัฒนา VB.NET:

    Public Shared Function GetFromFileName(ByVal fileName As String) As String
        Return GetFromExtension(Path.GetExtension(fileName).Remove(0, 1))
    End Function

    Public Shared Function GetFromExtension(ByVal extension As String) As String
        If extension.StartsWith("."c) Then
            extension = extension.Remove(0, 1)
        End If

        If MIMETypesDictionary.ContainsKey(extension) Then
            Return MIMETypesDictionary(extension)
        End If

        Return "unknown/unknown"
    End Function

    Private Shared ReadOnly MIMETypesDictionary As New Dictionary(Of String, String)() From { _
         {"ai", "application/postscript"}, _
         {"aif", "audio/x-aiff"}, _
         {"aifc", "audio/x-aiff"}, _
         {"aiff", "audio/x-aiff"}, _
         {"asc", "text/plain"}, _
         {"atom", "application/atom+xml"}, _
         {"au", "audio/basic"}, _
         {"avi", "video/x-msvideo"}, _
         {"bcpio", "application/x-bcpio"}, _
         {"bin", "application/octet-stream"}, _
         {"bmp", "image/bmp"}, _
         {"cdf", "application/x-netcdf"}, _
         {"cgm", "image/cgm"}, _
         {"class", "application/octet-stream"}, _
         {"cpio", "application/x-cpio"}, _
         {"cpt", "application/mac-compactpro"}, _
         {"csh", "application/x-csh"}, _
         {"css", "text/css"}, _
         {"dcr", "application/x-director"}, _
         {"dif", "video/x-dv"}, _
         {"dir", "application/x-director"}, _
         {"djv", "image/vnd.djvu"}, _
         {"djvu", "image/vnd.djvu"}, _
         {"dll", "application/octet-stream"}, _
         {"dmg", "application/octet-stream"}, _
         {"dms", "application/octet-stream"}, _
         {"doc", "application/msword"}, _
         {"dtd", "application/xml-dtd"}, _
         {"dv", "video/x-dv"}, _
         {"dvi", "application/x-dvi"}, _
         {"dxr", "application/x-director"}, _
         {"eps", "application/postscript"}, _
         {"etx", "text/x-setext"}, _
         {"exe", "application/octet-stream"}, _
         {"ez", "application/andrew-inset"}, _
         {"gif", "image/gif"}, _
         {"gram", "application/srgs"}, _
         {"grxml", "application/srgs+xml"}, _
         {"gtar", "application/x-gtar"}, _
         {"hdf", "application/x-hdf"}, _
         {"hqx", "application/mac-binhex40"}, _
         {"htm", "text/html"}, _
         {"html", "text/html"}, _
         {"ice", "x-conference/x-cooltalk"}, _
         {"ico", "image/x-icon"}, _
         {"ics", "text/calendar"}, _
         {"ief", "image/ief"}, _
         {"ifb", "text/calendar"}, _
         {"iges", "model/iges"}, _
         {"igs", "model/iges"}, _
         {"jnlp", "application/x-java-jnlp-file"}, _
         {"jp2", "image/jp2"}, _
         {"jpe", "image/jpeg"}, _
         {"jpeg", "image/jpeg"}, _
         {"jpg", "image/jpeg"}, _
         {"js", "application/x-javascript"}, _
         {"kar", "audio/midi"}, _
         {"latex", "application/x-latex"}, _
         {"lha", "application/octet-stream"}, _
         {"lzh", "application/octet-stream"}, _
         {"m3u", "audio/x-mpegurl"}, _
         {"m4a", "audio/mp4a-latm"}, _
         {"m4b", "audio/mp4a-latm"}, _
         {"m4p", "audio/mp4a-latm"}, _
         {"m4u", "video/vnd.mpegurl"}, _
         {"m4v", "video/x-m4v"}, _
         {"mac", "image/x-macpaint"}, _
         {"man", "application/x-troff-man"}, _
         {"mathml", "application/mathml+xml"}, _
         {"me", "application/x-troff-me"}, _
         {"mesh", "model/mesh"}, _
         {"mid", "audio/midi"}, _
         {"midi", "audio/midi"}, _
         {"mif", "application/vnd.mif"}, _
         {"mov", "video/quicktime"}, _
         {"movie", "video/x-sgi-movie"}, _
         {"mp2", "audio/mpeg"}, _
         {"mp3", "audio/mpeg"}, _
         {"mp4", "video/mp4"}, _
         {"mpe", "video/mpeg"}, _
         {"mpeg", "video/mpeg"}, _
         {"mpg", "video/mpeg"}, _
         {"mpga", "audio/mpeg"}, _
         {"ms", "application/x-troff-ms"}, _
         {"msh", "model/mesh"}, _
         {"mxu", "video/vnd.mpegurl"}, _
         {"nc", "application/x-netcdf"}, _
         {"oda", "application/oda"}, _
         {"ogg", "application/ogg"}, _
         {"pbm", "image/x-portable-bitmap"}, _
         {"pct", "image/pict"}, _
         {"pdb", "chemical/x-pdb"}, _
         {"pdf", "application/pdf"}, _
         {"pgm", "image/x-portable-graymap"}, _
         {"pgn", "application/x-chess-pgn"}, _
         {"pic", "image/pict"}, _
         {"pict", "image/pict"}, _
         {"png", "image/png"}, _
         {"pnm", "image/x-portable-anymap"}, _
         {"pnt", "image/x-macpaint"}, _
         {"pntg", "image/x-macpaint"}, _
         {"ppm", "image/x-portable-pixmap"}, _
         {"ppt", "application/vnd.ms-powerpoint"}, _
         {"ps", "application/postscript"}, _
         {"qt", "video/quicktime"}, _
         {"qti", "image/x-quicktime"}, _
         {"qtif", "image/x-quicktime"}, _
         {"ra", "audio/x-pn-realaudio"}, _
         {"ram", "audio/x-pn-realaudio"}, _
         {"ras", "image/x-cmu-raster"}, _
         {"rdf", "application/rdf+xml"}, _
         {"rgb", "image/x-rgb"}, _
         {"rm", "application/vnd.rn-realmedia"}, _
         {"roff", "application/x-troff"}, _
         {"rtf", "text/rtf"}, _
         {"rtx", "text/richtext"}, _
         {"sgm", "text/sgml"}, _
         {"sgml", "text/sgml"}, _
         {"sh", "application/x-sh"}, _
         {"shar", "application/x-shar"}, _
         {"silo", "model/mesh"}, _
         {"sit", "application/x-stuffit"}, _
         {"skd", "application/x-koan"}, _
         {"skm", "application/x-koan"}, _
         {"skp", "application/x-koan"}, _
         {"skt", "application/x-koan"}, _
         {"smi", "application/smil"}, _
         {"smil", "application/smil"}, _
         {"snd", "audio/basic"}, _
         {"so", "application/octet-stream"}, _
         {"spl", "application/x-futuresplash"}, _
         {"src", "application/x-wais-source"}, _
         {"sv4cpio", "application/x-sv4cpio"}, _
         {"sv4crc", "application/x-sv4crc"}, _
         {"svg", "image/svg+xml"}, _
         {"swf", "application/x-shockwave-flash"}, _
         {"t", "application/x-troff"}, _
         {"tar", "application/x-tar"}, _
         {"tcl", "application/x-tcl"}, _
         {"tex", "application/x-tex"}, _
         {"texi", "application/x-texinfo"}, _
         {"texinfo", "application/x-texinfo"}, _
         {"tif", "image/tiff"}, _
         {"tiff", "image/tiff"}, _
         {"tr", "application/x-troff"}, _
         {"tsv", "text/tab-separated-values"}, _
         {"txt", "text/plain"}, _
         {"ustar", "application/x-ustar"}, _
         {"vcd", "application/x-cdlink"}, _
         {"vrml", "model/vrml"}, _
         {"vxml", "application/voicexml+xml"}, _
         {"wav", "audio/x-wav"}, _
         {"wbmp", "image/vnd.wap.wbmp"}, _
         {"wbmxl", "application/vnd.wap.wbxml"}, _
         {"wml", "text/vnd.wap.wml"}, _
         {"wmlc", "application/vnd.wap.wmlc"}, _
         {"wmls", "text/vnd.wap.wmlscript"}, _
         {"wmlsc", "application/vnd.wap.wmlscriptc"}, _
         {"wrl", "model/vrml"}, _
         {"xbm", "image/x-xbitmap"}, _
         {"xht", "application/xhtml+xml"}, _
         {"xhtml", "application/xhtml+xml"}, _
         {"xls", "application/vnd.ms-excel"}, _
         {"xml", "application/xml"}, _
         {"xpm", "image/x-xpixmap"}, _
         {"xsl", "application/xml"}, _
         {"xslt", "application/xslt+xml"}, _
         {"xul", "application/vnd.mozilla.xul+xml"}, _
         {"xwd", "image/x-xwindowdump"}, _
         {"xyz", "chemical/x-xyz"}, _
         {"zip", "application/zip"} _
        }

4
ดูเหมือนว่ามันอาจจะเป็นรายการเก่า ... no .docx, .xlsx ฯลฯ
JoelFan

มีรายการออนไลน์ที่ไหนสักแห่ง? รายการด้านบนดูสมบูรณ์ขึ้นเล็กน้อยและพบบางส่วนที่ขาดหายไปที่นี่: stackoverflow.com/questions/4212861/ … - แต่ดูเหมือนว่าควรมีบริการเว็บที่คุณสามารถส่งชื่อไฟล์และบางไบต์ ด้วยที่สามารถคาดเดาได้ดีที่สุดและหาที่เหลือ ...
BrainSlugs83

ฉันจะใช้การกำหนดค่าสำหรับสิ่งนี้ดังนั้นฉันสามารถเลือกประเภท mime ที่ฉันต้องการและปรับเปลี่ยนได้ตามความเหมาะสมโดยไม่ต้องเปลี่ยนรหัสบรรทัดเดียว
Ivaylo Slavov

2

ฉันเจอปัญหาเดียวกันและในที่สุดก็เลือกที่จะแก้ปัญหาของ Kirk Baucom ในแบบของฉันเองที่นี่พบได้ที่นี่

สำหรับฉันดูเหมือนว่านี่เป็นโอกาสสำหรับบางคนที่จะเขียนบริการค้นหาออนไลน์

อย่างไรก็ตามหวังว่ามันจะช่วย


2

หากมีคนใช้มันพวกเขาสามารถพอร์ตโมดูล Perl ที่ยอดเยี่ยมFile :: Type to .NET ในรหัสคือชุดของหมายเลขมายากลไฟล์ส่วนหัวค้นหาสำหรับแต่ละประเภทไฟล์หรือการแข่งขัน regex

นี่คือ. NET ไฟล์ประเภทที่ตรวจจับไลบรารีhttp://filetypedetective.codeplex.com/แต่ตรวจพบไฟล์ได้เพียงเล็กน้อยเท่านั้นในขณะนี้


2

คำตอบนี้เป็นสำเนาของคำตอบของผู้เขียน (Richard Gourlay) แต่ได้รับการปรับปรุงเพื่อแก้ไขปัญหาใน IIS 8 / win2012 (โดยที่ฟังก์ชันจะทำให้แอพพูลผิดพลาด) ตามความคิดเห็นของ Rohland ชี้ไปที่http://www.pinvoke.net /default.aspx/urlmon.findmimefromdata

using System.Runtime.InteropServices;

...

public static string GetMimeFromFile(string filename)
{

    if (!File.Exists(filename))
        throw new FileNotFoundException(filename + " not found");

    const int maxContent = 256;

    var buffer = new byte[maxContent];
    using (var fs = new FileStream(filename, FileMode.Open))
    {
        if (fs.Length >= maxContent)
            fs.Read(buffer, 0, maxContent);
        else
            fs.Read(buffer, 0, (int) fs.Length);
    }

    var mimeTypePtr = IntPtr.Zero;
    try
    {
        var result = FindMimeFromData(IntPtr.Zero, null, buffer, maxContent, null, 0, out mimeTypePtr, 0);
        if (result != 0)
        {
            Marshal.FreeCoTaskMem(mimeTypePtr);
            throw Marshal.GetExceptionForHR(result);
        }

        var mime = Marshal.PtrToStringUni(mimeTypePtr);
        Marshal.FreeCoTaskMem(mimeTypePtr);
        return mime;
    }
    catch (Exception e)
    {
        if (mimeTypePtr != IntPtr.Zero)
        {
            Marshal.FreeCoTaskMem(mimeTypePtr);
        }
        return "unknown/unknown";
    }
}

[DllImport("urlmon.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]
private 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);

Nice C + P สามารถตอบได้ Chrs
พัฒนา MemeDev

2

@Steve Morgan และ @Richard Gourlay นี่เป็นทางออกที่ยอดเยี่ยมขอบคุณสำหรับสิ่งนั้น ข้อเสียเปรียบเล็ก ๆ อย่างหนึ่งคือเมื่อจำนวนไบต์ในไฟล์เป็น 255 หรือต่ำกว่าบางครั้งชนิด mime จะให้ผล "application / octet-stream" ซึ่งไม่ถูกต้องเล็กน้อยสำหรับไฟล์ที่คาดว่าจะให้ "text / plain" เล็กน้อย ฉันได้อัปเดตวิธีดั้งเดิมของคุณเป็นบัญชีสำหรับสถานการณ์นี้ดังนี้:

หากจำนวนไบต์ในไฟล์น้อยกว่าหรือเท่ากับ 255 และชนิด mime ที่อนุมานได้คือ "application / octet-stream" ดังนั้นให้สร้างอาร์เรย์ไบต์ใหม่ที่ประกอบด้วยไบต์ไฟล์ดั้งเดิมที่ทำซ้ำ n-times จนกระทั่งจำนวนทั้งหมด of bytes คือ> = 256 จากนั้นตรวจสอบ mime-type บนอาร์เรย์ไบต์ใหม่นั้นอีกครั้ง

วิธีการแก้ไข:

Imports System.Runtime.InteropServices

<DllImport("urlmon.dll", CharSet:=CharSet.Auto)> _
Private Shared Function FindMimeFromData(pBC As System.UInt32, <MarshalAs(UnmanagedType.LPStr)> pwzUrl As System.String, <MarshalAs(UnmanagedType.LPArray)> pBuffer As Byte(), cbSize As System.UInt32, <MarshalAs(UnmanagedType.LPStr)> pwzMimeProposed As System.String, dwMimeFlags As System.UInt32, _
ByRef ppwzMimeOut As System.UInt32, dwReserverd As System.UInt32) As System.UInt32
End Function
Private Function GetMimeType(ByVal f As FileInfo) As String
    'See http://stackoverflow.com/questions/58510/using-net-how-can-you-find-the-mime-type-of-a-file-based-on-the-file-signature
    Dim returnValue As String = ""
    Dim fileStream As FileStream = Nothing
    Dim fileStreamLength As Long = 0
    Dim fileStreamIsLessThanBByteSize As Boolean = False

    Const byteSize As Integer = 255
    Const bbyteSize As Integer = byteSize + 1

    Const ambiguousMimeType As String = "application/octet-stream"
    Const unknownMimeType As String = "unknown/unknown"

    Dim buffer As Byte() = New Byte(byteSize) {}
    Dim fnGetMimeTypeValue As New Func(Of Byte(), Integer, String)(
        Function(_buffer As Byte(), _bbyteSize As Integer) As String
            Dim _returnValue As String = ""
            Dim mimeType As UInt32 = 0
            FindMimeFromData(0, Nothing, _buffer, _bbyteSize, Nothing, 0, mimeType, 0)
            Dim mimeTypePtr As IntPtr = New IntPtr(mimeType)
            _returnValue = Marshal.PtrToStringUni(mimeTypePtr)
            Marshal.FreeCoTaskMem(mimeTypePtr)
            Return _returnValue
        End Function)

    If (f.Exists()) Then
        Try
            fileStream = New FileStream(f.FullName(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
            fileStreamLength = fileStream.Length()

            If (fileStreamLength >= bbyteSize) Then
                fileStream.Read(buffer, 0, bbyteSize)
            Else
                fileStreamIsLessThanBByteSize = True
                fileStream.Read(buffer, 0, CInt(fileStreamLength))
            End If

            returnValue = fnGetMimeTypeValue(buffer, bbyteSize)

            If (returnValue.Equals(ambiguousMimeType, StringComparison.OrdinalIgnoreCase) AndAlso fileStreamIsLessThanBByteSize AndAlso fileStreamLength > 0) Then
                'Duplicate the stream content until the stream length is >= bbyteSize to get a more deterministic mime type analysis.
                Dim currentBuffer As Byte() = buffer.Take(fileStreamLength).ToArray()
                Dim repeatCount As Integer = Math.Floor((bbyteSize / fileStreamLength) + 1)
                Dim bBufferList As List(Of Byte) = New List(Of Byte)
                While (repeatCount > 0)
                    bBufferList.AddRange(currentBuffer)
                    repeatCount -= 1
                End While
                Dim bbuffer As Byte() = bBufferList.Take(bbyteSize).ToArray()
                returnValue = fnGetMimeTypeValue(bbuffer, bbyteSize)
            End If
        Catch ex As Exception
            returnValue = unknownMimeType
        Finally
            If (fileStream IsNot Nothing) Then fileStream.Close()
        End Try
    End If
    Return returnValue
End Function

นี่เป็นปัญหาที่ฉันมีและความคิดของคุณยอดเยี่ยมในการคัดลอกไบต์ ฉันต้องใช้มันใน c # แต่ใช้ความยาวของไฟล์และบัฟเฟอร์ที่มีไบต์แรกของไฟล์ฉันสามารถวนซ้ำไบต์ที่หายไปทั้งหมดและคัดลอกไบต์ในอาร์เรย์เพื่อทำซ้ำไฟล์ (i เพิ่งคัดลอกไบต์จาก idx ที่เป็นความยาวไฟล์ก่อนหน้านี้ในอาร์เรย์)
Richard Duerr

1

IIS 7 ขึ้นไป

ใช้รหัสนี้ แต่คุณต้องเป็นผู้ดูแลระบบบนเซิร์ฟเวอร์

public bool CheckMimeMapExtension(string fileExtension)
        {
            try
            {

                using (
                ServerManager serverManager = new ServerManager())
                {   
                    // connects to default app.config
                    var config = serverManager.GetApplicationHostConfiguration();
                    var staticContent = config.GetSection("system.webServer/staticContent");
                    var mimeMap = staticContent.GetCollection();

                    foreach (var mimeType in mimeMap)
                    {

                        if (((String)mimeType["fileExtension"]).Equals(fileExtension, StringComparison.OrdinalIgnoreCase))
                            return true;

                    }

                }
                return false;
            }
            catch (Exception ex)
            { 
                Console.WriteLine("An exception has occurred: \n{0}", ex.Message);
                Console.Read();
            }

            return false;

        }

สิ่งที่เกี่ยวกับการปลอมแปลง?
TS

0

เมื่อทำงานกับบทบาท Windows Azure Web หรือโฮสต์อื่น ๆ ที่รันแอพของคุณใน Limited Trust อย่าลืมว่าคุณจะไม่ได้รับอนุญาตให้เข้าถึงรีจิสตรีหรือโค้ดที่ไม่มีการจัดการ วิธีไฮบริด - การรวมกันของการลองจับรีจิสทรีและพจนานุกรมในหน่วยความจำดูเหมือนว่าเป็นทางออกที่ดีที่มีทุกอย่าง

ฉันใช้รหัสนี้เพื่อทำ:

public class DefaultMimeResolver : IMimeResolver
{
    private readonly IFileRepository _fileRepository;

    public DefaultMimeResolver(IFileRepository fileRepository)
    {
        _fileRepository = fileRepository;
    }

    [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
    private static extern System.UInt32 FindMimeFromData(
        System.UInt32 pBC, [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl,
         [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
         System.UInt32 cbSize,
         [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed,
         System.UInt32 dwMimeFlags,
         out System.UInt32 ppwzMimeOut,
         System.UInt32 dwReserverd);


    public string GetMimeTypeFromFileExtension(string fileExtension)
    {
        if (string.IsNullOrEmpty(fileExtension))
        {
            throw new ArgumentNullException("fileExtension");
        }

        string mimeType = GetMimeTypeFromList(fileExtension);

        if (String.IsNullOrEmpty(mimeType))
        {
            mimeType = GetMimeTypeFromRegistry(fileExtension);
        }

        return mimeType;
    }

    public string GetMimeTypeFromFile(string filePath)
    {
        if (string.IsNullOrEmpty(filePath))
        {
            throw new ArgumentNullException("filePath");
        }

        if (!File.Exists(filePath))
        {
            throw new FileNotFoundException("File not found : ", filePath);
        }

        string mimeType = GetMimeTypeFromList(Path.GetExtension(filePath).ToLower());

        if (String.IsNullOrEmpty(mimeType))
        {
            mimeType = GetMimeTypeFromRegistry(Path.GetExtension(filePath).ToLower());

            if (String.IsNullOrEmpty(mimeType))
            {
                mimeType = GetMimeTypeFromFileInternal(filePath);
            }
        }

        return mimeType;
    }

    private string GetMimeTypeFromList(string fileExtension)
    {
        string mimeType = null;

        if (fileExtension.StartsWith("."))
        {
            fileExtension = fileExtension.TrimStart('.');
        }

        if (!String.IsNullOrEmpty(fileExtension) && _mimeTypes.ContainsKey(fileExtension))
        {
            mimeType = _mimeTypes[fileExtension];
        }

        return mimeType;
    }

    private string GetMimeTypeFromRegistry(string fileExtension)
    {
        string mimeType = null;
        try
        {
            RegistryKey key = Registry.ClassesRoot.OpenSubKey(fileExtension);

            if (key != null && key.GetValue("Content Type") != null)
            {
                mimeType = key.GetValue("Content Type").ToString();
            }
        }
        catch (Exception)
        {
            // Empty. When this code is running in limited mode accessing registry is not allowed.
        }

        return mimeType;
    }

    private string GetMimeTypeFromFileInternal(string filePath)
    {
        string mimeType = null;

        if (!File.Exists(filePath))
        {
            return null;
        }

        byte[] byteBuffer = new byte[256];

        using (FileStream fileStream = _fileRepository.Get(filePath))
        {
            if (fileStream.Length >= 256)
            {
                fileStream.Read(byteBuffer, 0, 256);
            }
            else
            {
                fileStream.Read(byteBuffer, 0, (int)fileStream.Length);
            }
        }

        try
        {
            UInt32 MimeTypeNum;

            FindMimeFromData(0, null, byteBuffer, 256, null, 0, out MimeTypeNum, 0);

            IntPtr mimeTypePtr = new IntPtr(MimeTypeNum);
            string mimeTypeFromFile = Marshal.PtrToStringUni(mimeTypePtr);

            Marshal.FreeCoTaskMem(mimeTypePtr);

            if (!String.IsNullOrEmpty(mimeTypeFromFile) && mimeTypeFromFile != "text/plain" && mimeTypeFromFile != "application/octet-stream")
            {
                mimeType = mimeTypeFromFile;
            }
        }
        catch
        {
            // Empty. 
        }

        return mimeType;
    }

    private readonly Dictionary<string, string> _mimeTypes = new Dictionary<string, string>
        {
            {"ai", "application/postscript"},
            {"aif", "audio/x-aiff"},
            {"aifc", "audio/x-aiff"},
            {"aiff", "audio/x-aiff"},
            {"asc", "text/plain"},
            {"atom", "application/atom+xml"},
            {"au", "audio/basic"},
            {"avi", "video/x-msvideo"},
            {"bcpio", "application/x-bcpio"},
            {"bin", "application/octet-stream"},
            {"bmp", "image/bmp"},
            {"cdf", "application/x-netcdf"},
            {"cgm", "image/cgm"},
            {"class", "application/octet-stream"},
            {"cpio", "application/x-cpio"},
            {"cpt", "application/mac-compactpro"},
            {"csh", "application/x-csh"},
            {"css", "text/css"},
            {"dcr", "application/x-director"},
            {"dif", "video/x-dv"},
            {"dir", "application/x-director"},
            {"djv", "image/vnd.djvu"},
            {"djvu", "image/vnd.djvu"},
            {"dll", "application/octet-stream"},
            {"dmg", "application/octet-stream"},
            {"dms", "application/octet-stream"},
            {"doc", "application/msword"},
            {"docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
            {"dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"},
            {"docm", "application/vnd.ms-word.document.macroEnabled.12"},
            {"dotm", "application/vnd.ms-word.template.macroEnabled.12"},
            {"dtd", "application/xml-dtd"},
            {"dv", "video/x-dv"},
            {"dvi", "application/x-dvi"},
            {"dxr", "application/x-director"},
            {"eps", "application/postscript"},
            {"etx", "text/x-setext"},
            {"exe", "application/octet-stream"},
            {"ez", "application/andrew-inset"},
            {"gif", "image/gif"},
            {"gram", "application/srgs"},
            {"grxml", "application/srgs+xml"},
            {"gtar", "application/x-gtar"},
            {"hdf", "application/x-hdf"},
            {"hqx", "application/mac-binhex40"},
            {"htc", "text/x-component"},
            {"htm", "text/html"},
            {"html", "text/html"},
            {"ice", "x-conference/x-cooltalk"},
            {"ico", "image/x-icon"},
            {"ics", "text/calendar"},
            {"ief", "image/ief"},
            {"ifb", "text/calendar"},
            {"iges", "model/iges"},
            {"igs", "model/iges"},
            {"jnlp", "application/x-java-jnlp-file"},
            {"jp2", "image/jp2"},
            {"jpe", "image/jpeg"},
            {"jpeg", "image/jpeg"},
            {"jpg", "image/jpeg"},
            {"js", "application/x-javascript"},
            {"kar", "audio/midi"},
            {"latex", "application/x-latex"},
            {"lha", "application/octet-stream"},
            {"lzh", "application/octet-stream"},
            {"m3u", "audio/x-mpegurl"},
            {"m4a", "audio/mp4a-latm"},
            {"m4b", "audio/mp4a-latm"},
            {"m4p", "audio/mp4a-latm"},
            {"m4u", "video/vnd.mpegurl"},
            {"m4v", "video/x-m4v"},
            {"mac", "image/x-macpaint"},
            {"man", "application/x-troff-man"},
            {"mathml", "application/mathml+xml"},
            {"me", "application/x-troff-me"},
            {"mesh", "model/mesh"},
            {"mid", "audio/midi"},
            {"midi", "audio/midi"},
            {"mif", "application/vnd.mif"},
            {"mov", "video/quicktime"},
            {"movie", "video/x-sgi-movie"},
            {"mp2", "audio/mpeg"},
            {"mp3", "audio/mpeg"},
            {"mp4", "video/mp4"},
            {"mpe", "video/mpeg"},
            {"mpeg", "video/mpeg"},
            {"mpg", "video/mpeg"},
            {"mpga", "audio/mpeg"},
            {"ms", "application/x-troff-ms"},
            {"msh", "model/mesh"},
            {"mxu", "video/vnd.mpegurl"},
            {"nc", "application/x-netcdf"},
            {"oda", "application/oda"},
            {"ogg", "application/ogg"},
            {"pbm", "image/x-portable-bitmap"},
            {"pct", "image/pict"},
            {"pdb", "chemical/x-pdb"},
            {"pdf", "application/pdf"},
            {"pgm", "image/x-portable-graymap"},
            {"pgn", "application/x-chess-pgn"},
            {"pic", "image/pict"},
            {"pict", "image/pict"},
            {"png", "image/png"},
            {"pnm", "image/x-portable-anymap"},
            {"pnt", "image/x-macpaint"},
            {"pntg", "image/x-macpaint"},
            {"ppm", "image/x-portable-pixmap"},
            {"ppt", "application/vnd.ms-powerpoint"},
            {"pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
            {"potx", "application/vnd.openxmlformats-officedocument.presentationml.template"},
            {"ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"},
            {"ppam", "application/vnd.ms-powerpoint.addin.macroEnabled.12"},
            {"pptm", "application/vnd.ms-powerpoint.presentation.macroEnabled.12"},
            {"potm", "application/vnd.ms-powerpoint.template.macroEnabled.12"},
            {"ppsm", "application/vnd.ms-powerpoint.slideshow.macroEnabled.12"},
            {"ps", "application/postscript"},
            {"qt", "video/quicktime"},
            {"qti", "image/x-quicktime"},
            {"qtif", "image/x-quicktime"},
            {"ra", "audio/x-pn-realaudio"},
            {"ram", "audio/x-pn-realaudio"},
            {"ras", "image/x-cmu-raster"},
            {"rdf", "application/rdf+xml"},
            {"rgb", "image/x-rgb"},
            {"rm", "application/vnd.rn-realmedia"},
            {"roff", "application/x-troff"},
            {"rtf", "text/rtf"},
            {"rtx", "text/richtext"},
            {"sgm", "text/sgml"},
            {"sgml", "text/sgml"},
            {"sh", "application/x-sh"},
            {"shar", "application/x-shar"},
            {"silo", "model/mesh"},
            {"sit", "application/x-stuffit"},
            {"skd", "application/x-koan"},
            {"skm", "application/x-koan"},
            {"skp", "application/x-koan"},
            {"skt", "application/x-koan"},
            {"smi", "application/smil"},
            {"smil", "application/smil"},
            {"snd", "audio/basic"},
            {"so", "application/octet-stream"},
            {"spl", "application/x-futuresplash"},
            {"src", "application/x-wais-source"},
            {"sv4cpio", "application/x-sv4cpio"},
            {"sv4crc", "application/x-sv4crc"},
            {"svg", "image/svg+xml"},
            {"swf", "application/x-shockwave-flash"},
            {"t", "application/x-troff"},
            {"tar", "application/x-tar"},
            {"tcl", "application/x-tcl"},
            {"tex", "application/x-tex"},
            {"texi", "application/x-texinfo"},
            {"texinfo", "application/x-texinfo"},
            {"tif", "image/tiff"},
            {"tiff", "image/tiff"},
            {"tr", "application/x-troff"},
            {"tsv", "text/tab-separated-values"},
            {"txt", "text/plain"},
            {"ustar", "application/x-ustar"},
            {"vcd", "application/x-cdlink"},
            {"vrml", "model/vrml"},
            {"vxml", "application/voicexml+xml"},
            {"wav", "audio/x-wav"},
            {"wbmp", "image/vnd.wap.wbmp"},
            {"wbmxl", "application/vnd.wap.wbxml"},
            {"wml", "text/vnd.wap.wml"},
            {"wmlc", "application/vnd.wap.wmlc"},
            {"wmls", "text/vnd.wap.wmlscript"},
            {"wmlsc", "application/vnd.wap.wmlscriptc"},
            {"wrl", "model/vrml"},
            {"xbm", "image/x-xbitmap"},
            {"xht", "application/xhtml+xml"},
            {"xhtml", "application/xhtml+xml"},
            {"xls", "application/vnd.ms-excel"},
            {"xml", "application/xml"},
            {"xpm", "image/x-xpixmap"},
            {"xsl", "application/xml"},
            {"xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
            {"xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"},
            {"xlsm", "application/vnd.ms-excel.sheet.macroEnabled.12"},
            {"xltm", "application/vnd.ms-excel.template.macroEnabled.12"},
            {"xlam", "application/vnd.ms-excel.addin.macroEnabled.12"},
            {"xlsb", "application/vnd.ms-excel.sheet.binary.macroEnabled.12"},
            {"xslt", "application/xslt+xml"},
            {"xul", "application/vnd.mozilla.xul+xml"},
            {"xwd", "image/x-xwindowdump"},
            {"xyz", "chemical/x-xyz"},
            {"zip", "application/zip"}
        };
}

ฉันจะซาบซึ้งความคิดเห็นใด ๆ เกี่ยวกับการลงคะแนนเสียง - ฉันต้องการเรียนรู้เกี่ยวกับการกระทำผิดที่อาจเกิดขึ้นของรหัสนี้
Ognyan Dimitrov

ฉันไม่เห็นบล็อกการลองจับในโค้ดของคุณเมื่อคุณใช้ GetMimeTypeFromFileInternal ดังนั้นดูเหมือนว่าโดยปกติคุณจะตรวจสอบนามสกุลไฟล์ซึ่งไม่เป็นประโยชน์หากคุณไม่แน่ใจว่ามีอะไรอยู่ในไฟล์ และฉันยังไม่สามารถรับได้ GetMimeTypeFromFileInternal ทำงานใน Azure กับ Limited Trust หรือไม่ ถ้าไม่เช่นนั้นทำไมมันยังอยู่ในรหัส?
Alexander Skogorev

1
ในกรณีของบริบทการดำเนินการที่ จำกัด คุณสามารถ จำกัด รหัสเพื่อใช้เฉพาะรายการ ใช่มีส่วนขยายมากกว่านั้น แต่มีเพียงนักพัฒนาเท่านั้นที่รู้บริบทของแอปพลิเคชันและสามารถเพิ่มมากขึ้นในรายการ และลองจับก็เป็นสิ่งที่ดีที่แน่นอน
Ognyan Dimitrov

0

ฉันลงเอยด้วยการใช้ Winista MimeDetector จาก Netomatix แหล่งที่มาสามารถดาวน์โหลดได้ฟรีหลังจากที่คุณสร้างบัญชี: http://www.netomatix.com/Products/DocumentManagement/MimeDetector.aspx

MimeTypes g_MimeTypes = new MimeTypes("mime-types.xml");
sbyte [] fileData = null;

using (System.IO.FileStream srcFile = new System.IO.FileStream(strFile, System.IO.FileMode.Open))
{
    byte [] data = new byte[srcFile.Length];
    srcFile.Read(data, 0, (Int32)srcFile.Length);
    fileData = Winista.Mime.SupportUtil.ToSByteArray(data);
}

MimeType oMimeType = g_MimeTypes.GetMimeType(fileData);

นี่เป็นส่วนหนึ่งของคำถามอื่นตอบที่นี่: วิธีการ FindMimeFromData ใน Urlmon.dll หนึ่งซึ่งมีชนิด MIME เพิ่มเติม วิธีที่ดีที่สุดในการแก้ไขปัญหานี้ในความคิดของฉัน


0

ฉันพบปัญหาหลายประการในการใช้งานรหัสนี้:

UInt32 mimetype;
FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);

หากคุณจะพยายามเรียกใช้ด้วย x64 / Win10 คุณจะได้รับ

AccessViolationException "Attempted to read or write protected memory.
This is often an indication that other memory is corrupt"

ขอบคุณโพสต์นี้PtrToStringUni ไม่ทำงานใน windows 10และ @xanatos

ฉันแก้ไขโซลูชันเพื่อทำงานภายใต้ x64 และ. NET Core 2.1:

   [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);

   string getMimeFromFile(byte[] fileSource)
   {
            byte[] buffer = new byte[256];
            using (Stream stream = new MemoryStream(fileSource))
            {
                if (stream.Length >= 256)
                    stream.Read(buffer, 0, 256);
                else
                    stream.Read(buffer, 0, (int)stream.Length);
            }

            try
            {
                IntPtr mimeTypePtr;
                FindMimeFromData(IntPtr.Zero, null, buffer, buffer.Length,
                    null, 0, out mimeTypePtr, 0);

                string mime = Marshal.PtrToStringUni(mimeTypePtr);
                Marshal.FreeCoTaskMem(mimeTypePtr);
                return mime;
            }
            catch (Exception ex)
            {
                return "unknown/unknown";
            }
   }

ขอบคุณ


0

สวัสดีครับได้ปรับโครงการ Winista.MimeDetect เข้า .net core / กรอบกับทางเลือกเข้า urlmon.dll Fell อิสระที่จะใช้: แพคเกจ nuget

   //init
   var mimeTypes = new MimeTypes();

   //usage by filepath
   var mimeType1 = mimeTypes.GetMimeTypeFromFile(filePath);

ตัวอย่างรหัส gihub เป็นความผิดที่นี่ github.com/GetoXs/MimeDetect ไม่มีการโอเวอร์โหลดmimeTypes.GetMimeTypeFromFile(bytes);
TS

0

ฉันเขียนโปรแกรมตรวจสอบประเภท mime กรุณาแบ่งปันกับคุณ

private readonly Dictionary<string, byte[]> _mimeTypes = new Dictionary<string, byte[]>
    {
        {"image/jpeg", new byte[] {255, 216, 255}},
        {"image/jpg", new byte[] {255, 216, 255}},
        {"image/pjpeg", new byte[] {255, 216, 255}},
        {"image/apng", new byte[] {137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82}},
        {"image/png", new byte[] {137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82}},
        {"image/bmp", new byte[] {66, 77}},
        {"image/gif", new byte[] {71, 73, 70, 56}},
    };

private bool ValidateMimeType(byte[] file, string contentType)
    {
        var imageType = _mimeTypes.SingleOrDefault(x => x.Key.Equals(contentType));

        return file.Take(imageType.Value.Length).SequenceEqual(imageType.Value);
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.