如何在运行时获取文件的内容/类型

34

我想动态确定输入文件的内容/类型。如果我在Windows应用程序中,我可以编写以下代码(从这篇博客中获取):

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

有哪些其他方法适用于MVC应用程序?

我想使用Controller.File(...)方法中的参数,该参数接收文件路径和内容类型。

7个回答

114

6
请注意,此问题已标记为asp.net,并且此MimeMapping是ASP.net扩展(System.Web.MimeMapping)。 - mvermand
有没有想法如何实现相反的操作?从MimeType获取扩展名? - Jackie
2
@Jackie 许多扩展名可以由单个MIME类型表示,因此反向映射并不总是有效。 - masterwok

20

重要提示:这个答案是在2011年写的,在masterwok的答案几年之前。虽然我的答案仍然可接受,但masterwok的答案更好、更简洁。请使用和投票那个答案。以下所有内容都是为了记录。

我只会使用文件扩展名,而不是试图做一些聪明的事情,这可能最终会让你后悔。 :)

文件扩展名不需要在您的系统上注册(尽管我不知道您正在处理文件的确切内容...)。如果您想要过滤文件,则可以使用诸如枚举或数据库表之类的东西,其中包含有关可接受扩展名的信息。

请参见@Tolgahan的想法。我根据此创建了一个C#枚举,它应该为人们提供一个起点,以便他们希望创建基于数据库/枚举/XML的方法来处理文件扩展名。

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

我正在尝试从控制器返回一个文件。我正在使用完全这种方法,因此使用确切的内容类型/ MIME类型也使客户端正确地行为(如呈现PDF,打开MS Word等)。 - Lorenzo
那么你只需要确保在将文件发送给客户端时传递正确的 content-disposition 头信息即可。 - Dan Atkinson
如果你担心安全问题,仅仅使用文件扩展名并不是特别安全的。 - handles

8

.NET CORE使用Microsoft.AspNetCore.StaticFiles

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

这是针对dotnet core时代的正确答案。但仍然想知道为什么他们没有一些简单的解决方案,而不是“Try…”这种方法。虽然它在我正在处理的控制台应用程序中帮助了我,而且无需安装任何第三方插件等。谢谢。 - sanpat

7

建议:将格式和扩展名数据(http://www.feedforall.com/mime-types.htm)放入xml文件或项目中作为字典、数组等形式进行查询,并创建一个确定扩展名的MIME类型过程。我认为将数据保存在xml文档中,在编译后进行修改会更容易。


有没有标准文件可以写下所有这些 MIME 类型? - Lorenzo
4
@Lorenzo:我已经擅自将那个文件翻译成了XML格式——http://pastebin.com/94ivivP4。 - Dan Atkinson

3
如果你想使用流(stream)
    public class urlmonMimeDetect
    {
        [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(Stream fs)
        {

            byte[] buffer = new byte[256];
            fs.Read(buffer, 0, 256);

            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";
            }
        }
    }

1

这个文件是上传到MVC应用程序中吗?

public ActionResult FileUploader(HttpPostedFileBase upload)
{
  string mimeType=upload.ContentType;
}

然而,这种方法有一些注意事项。

它使用浏览器提供的mime类型,如果上传文件的用户没有经过身份验证或信任,则可能不是一个好主意。

此外,IE并不总是为某些文件提供标准的Mime类型,特别是PNG格式的文件(请参见“image/png”和“image/x-png”之间的区别是什么?),这可能会影响您的应用程序。

我们只需使用简单的if语句将IE png mime类型(image/x-png)转换回更常见的类型(image/png)。


正如您可以从问题中读到的那样,我正在尝试将其用于下载而不是上传。我在Controller.File(...)方法调用的上下文中使用它。 - Lorenzo

0
如果您使用的是类似Linux/Unix的系统,您可以使用file命令来确定文件类型。

有三组测试按照以下顺序进行:文件系统测试、魔数测试和语言测试。第一个成功的测试会导致文件类型被打印出来。

如果您使用的是Windows机器,通常会使用文件扩展名,就像您在代码中展示的那样。

在一个Web应用程序中,我没有安装任何这些产品:Word、Excel、PowerPoint、Adobe等等。因此,我认为在注册表中没有可用的密钥,但也许我需要在MIME类型列表中注册类型。我该怎么做? - Lorenzo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接