如何从文件扩展名中获得MIME类型?
当前回答
受到塞缪尔回答的启发,我写了一个改进版本:
当扩展名是大写时也适用。 以文件名为输入,优雅地处理没有扩展名的文件。 不要在键中包含“。”。 列表,为此我编写了一个小型转换脚本。
最终的源代码超过30K个字符,所以我不能张贴在这里,在Github上检查它。
其他回答
如果有人能在linux上使用libmagic类似的功能,那就更好了,因为我认为这是一种比依赖文件扩展名更好的检测文件类型的方法。
例如,如果我将一个文件从myppicture .jpg重命名为myppicture .txt 在linux上,它仍然会被报告为一张图片 但是在这里使用这种方法,它将被报告为文本文件。
目光Tomas
我已经编译了一个有名的mime类型和内容类型值的来源列表,这些值仅以文件扩展名为键(目前)。
nuget包在这里https://www.nuget.org/packages/FTTLib.dll/
来源在这里https://github.com/brondavies/filetypetranslator/
这个库被设计成:
无外部依赖 没有文件系统访问权限 内存占用小 简单的静态方法(没有扩展方法和可实例化类) 不区分大小写 可移植-工作在应用程序针对任何CLR(。NET 2.0 +)
这个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
我已经编写了一个程序来获取和转换Apache mime。类型文件到c#字典<字符串,字符串>的关键文件扩展名。这里的。
实际的输出是这个文件(但是您可能希望获取它并再次运行它,以防Apache文件在我上次运行之后已经更新)。
public static Dictionary<string, string> MimeTypes = new Dictionary<string, string>
{
{ "123", "application/vnd.lotus-1-2-3" },
{ "3dml", "text/vnd.in3d.3dml" },
{ "3g2", "video/3gpp2" },
{ "3gp", "video/3gpp" },
{ "7z", "application/x-7z-compressed" },
{ "aab", "application/x-authorware-bin" },
{ "aac", "audio/x-aac" },
{ "aam", "application/x-authorware-map" },
{ "aas", "application/x-authorware-seg" },
{ "abw", "application/x-abiword" },
...
. net框架提供了获取mime类型的内置方法。不需要编写自定义代码。
string mimeType = System.Web.MimeMapping.GetMimeMapping(fileName);