如何从文件扩展名中获得MIME类型?


当前回答

这个helper类返回任何文件名的mime类型(内容类型)、描述和图标:

using Microsoft.Win32;
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;

public static class Helper
{
    [DllImport("shell32.dll", CharSet = CharSet.Auto)]
    private static extern int ExtractIconEx(string lpszFile, int nIconIndex, IntPtr[] phIconLarge, IntPtr[] phIconSmall, int nIcons);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern int DestroyIcon(IntPtr hIcon);

    public static string GetFileContentType(string fileName)
    {
        if (fileName == null)
        {
            throw new ArgumentNullException("fileName");
        }

        RegistryKey registryKey = null;
        try
        {
            FileInfo fileInfo = new FileInfo(fileName);

            if (string.IsNullOrEmpty(fileInfo.Extension))
            {
                return string.Empty;
            }

            string extension = fileInfo.Extension.ToLowerInvariant();

            registryKey = Registry.ClassesRoot.OpenSubKey(extension);
            if (registryKey == null)
            {
                return string.Empty;
            }

            object contentTypeObject = registryKey.GetValue("Content Type");
            if (!(contentTypeObject is string))
            {
                return string.Empty;
            }

            string contentType = (string)contentTypeObject;

            return contentType;
        }
        catch (Exception)
        {
            return null;
        }
        finally
        {
            if (registryKey != null)
            {
                registryKey.Close();
            }
        }
    }

    public static string GetFileDescription(string fileName)
    {
        if (fileName == null)
        {
            throw new ArgumentNullException("fileName");
        }

        RegistryKey registryKey1 = null;
        RegistryKey registryKey2 = null;
        try
        {
            FileInfo fileInfo = new FileInfo(fileName);

            if (string.IsNullOrEmpty(fileInfo.Extension))
            {
                return string.Empty;
            }

            string extension = fileInfo.Extension.ToLowerInvariant();

            registryKey1 = Registry.ClassesRoot.OpenSubKey(extension);
            if (registryKey1 == null)
            {
                return string.Empty;
            }

            object extensionDefaultObject = registryKey1.GetValue(null);
            if (!(extensionDefaultObject is string))
            {
                return string.Empty;
            }

            string extensionDefaultValue = (string)extensionDefaultObject;

            registryKey2 = Registry.ClassesRoot.OpenSubKey(extensionDefaultValue);
            if (registryKey2 == null)
            {
                return string.Empty;
            }

            object fileDescriptionObject = registryKey2.GetValue(null);
            if (!(fileDescriptionObject is string))
            {
                return string.Empty;
            }

            string fileDescription = (string)fileDescriptionObject;
            return fileDescription;
        }
        catch (Exception)
        {
            return null;
        }
        finally
        {
            if (registryKey2 != null)
            {
                registryKey2.Close();
            }

            if (registryKey1 != null)
            {
                registryKey1.Close();
            }
        }
    }

    public static void GetFileIcons(string fileName, out Icon smallIcon, out Icon largeIcon)
    {
        if (fileName == null)
        {
            throw new ArgumentNullException("fileName");
        }

        smallIcon = null;
        largeIcon = null;

        RegistryKey registryKey1 = null;
        RegistryKey registryKey2 = null;
        try
        {
            FileInfo fileInfo = new FileInfo(fileName);

            if (string.IsNullOrEmpty(fileInfo.Extension))
            {
                return;
            }

            string extension = fileInfo.Extension.ToLowerInvariant();

            registryKey1 = Registry.ClassesRoot.OpenSubKey(extension);
            if (registryKey1 == null)
            {
                return;
            }

            object extensionDefaultObject = registryKey1.GetValue(null);
            if (!(extensionDefaultObject is string))
            {
                return;
            }

            string defaultIconKeyName = string.Format("{0}\\DefaultIcon", extensionDefaultObject);

            registryKey2 = Registry.ClassesRoot.OpenSubKey(defaultIconKeyName);
            if (registryKey2 == null)
            {
                return;
            }

            object defaultIconPathObject = registryKey2.GetValue(null);
            if (!(defaultIconPathObject is string))
            {
                return;
            }

            string defaultIconPath = (string)defaultIconPathObject;
            if (string.IsNullOrWhiteSpace(defaultIconPath))
            {
                return;
            }

            string iconfileName = null;
            int iconIndex = 0;

            int commaIndex = defaultIconPath.IndexOf(",");
            if (commaIndex > 0)
            {
                iconfileName = defaultIconPath.Substring(0, commaIndex);
                string iconIndexString = defaultIconPath.Substring(commaIndex + 1);

                if (!int.TryParse(iconIndexString, out iconIndex))
                {
                    iconIndex = 0;
                }
            }
            else
            {
                iconfileName = defaultIconPath;
                iconIndex = 0;
            }

            IntPtr[] phiconSmall = new IntPtr[1] { IntPtr.Zero };
            IntPtr[] phiconLarge = new IntPtr[1] { IntPtr.Zero };

            int readIconCount = ExtractIconEx(iconfileName, iconIndex, phiconLarge, phiconSmall, 1);

            if (readIconCount < 0)
            {
                return;
            }

            if (phiconSmall[0] != IntPtr.Zero)
            {
                smallIcon = (Icon)Icon.FromHandle(phiconSmall[0]).Clone();
                DestroyIcon(phiconSmall[0]);
            }

            if (phiconLarge[0] != IntPtr.Zero)
            {
                largeIcon = (Icon)Icon.FromHandle(phiconLarge[0]).Clone();
                DestroyIcon(phiconLarge[0]);
            }

            return;
        }
        finally
        {
            if (registryKey2 != null)
            {
                registryKey2.Close();
            }

            if (registryKey1 != null)
            {
                registryKey1.Close();
            }
        }
    }
}

用法:

string fileName = "NotExists.txt";
string contentType = Helper.GetFileContentType(fileName); // "text/plain"
string description = Helper.GetFileDescription(fileName); // "Text Document"
Icon smallIcon, largeIcon;
Helper.GetFileIcons(fileName, out smallIcon, out largeIcon); // 16x16, 32x32 icons

其他回答

你可以使用这个helper函数:

private string GetMimeType (string fileName)
{
    string mimeType = "application/unknown";
    string ext = System.IO.Path.GetExtension(fileName).ToLower();
    Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
    if (regKey != null && regKey.GetValue("Content Type") != null)
    mimeType = regKey.GetValue("Content Type").ToString();
    return mimeType;
}

.NET Core获取MimeType的方法:

添加依赖关系

Microsoft.AspNetCore.StaticFiles

private string GetMimeType(string fileName)
{
    var provider = new FileExtensionContentTypeProvider();
    if (!provider.TryGetContentType(fileName, out var contentType))
    {
        contentType = "application/octet-stream";
    }
    return contentType;            
}

受到塞缪尔回答的启发,我写了一个改进版本:

当扩展名是大写时也适用。 以文件名为输入,优雅地处理没有扩展名的文件。 不要在键中包含“。”。 列表,为此我编写了一个小型转换脚本。

最终的源代码超过30K个字符,所以我不能张贴在这里,在Github上检查它。

使用MimeTypeMap包,它提供了文件扩展名到mime类型以及mime类型到文件扩展名的巨大双向映射

使用mimetype;

获取扩展的mime类型

Console.WriteLine("txt -> " + MimeTypeMap.GetMimeType("txt"));  // "text/plain"

获取mime类型的扩展名

Console.WriteLine("audio/wav -> " + MimeTypeMap.GetExtension("audio/wav")); // ".wav"

GitHub网址:https://github.com/samuelneff/MimeTypeMap

我对这些mimetypes的理解,使用apache列表,下面的脚本将为您提供一个包含所有mimetypes的字典。

var mimeTypeListUrl = "http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types";
var webClient = new WebClient();
var rawData = webClient.DownloadString(mimeTypeListUrl).Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.RemoveEmptyEntries);

var extensionToMimeType = new Dictionary<string, string>();
var mimeTypeToExtension = new Dictionary<string, string[]>();

foreach (var row in rawData)
{
    if (row.StartsWith("#")) continue;

    var rowData = row.Split(new[] { "\t" }, StringSplitOptions.RemoveEmptyEntries);
    if (rowData.Length != 2) continue;

    var extensions = rowData[1].Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
    if (!mimeTypeToExtension.ContainsKey(rowData[0]))
    {
        mimeTypeToExtension.Add(rowData[0], extensions);
    }

    foreach (var extension in extensions)
    {
        if (!extensionToMimeType.ContainsKey(extension))
        {
            extensionToMimeType.Add(extension, rowData[0]);
        }
    }

}