2011-06-23 111 views
1

我目前正面临一个我觉得比有趣的问题:检测给定文件的MIME类型。 通过检测,我的意思是只使用文件中存在的信息来猜测MIME类型。通过文件,我的意思是一个具有名称和内容的结构。Mime类型检测完成正确

这里是我知道这个问题的解决方案:

  • 试图猜测根据文件名的文件类型。例如,如果文件名是foo.txt,我可以假设MIME类型是text/plain
  • 尝试使用内容确定类型,特别是通常包含某种魔术代码的第一个字节。例如,如果文件以八位组号0xCAFEBABE开头,那么我可以假设MIME类型是application/x-java-class

这个问题的两种解决方法都有其优点和缺点。

第一个解决方案非常高效,但我们假设该文件具有正确的名称,并且具有扩展名。如何检测名为LICENSEREADME的文件的MIME类型?

第二种技术有点复杂,必须实际读取数据。它适用于所有包含魔术代码的文件,但对其他文件效果不佳。可能会出现一些问题:如何区分MS-DOS EXE文件(以MZ作为魔术代码开始)和以字母MZ开头的实际text/plain文件之间的区别。当您考虑其他文件类型(txt vs csv; html vs xml vs xhtml)时,许多类似的问题出现了。

因此,真正的问题来了: 如何有效和可靠地检测MIME类型的文件?


一些旁注:

  • 我知道很多很多图书馆的存在在那里,做的工作。我对图书馆不感兴趣。我有兴趣弄脏我的手。
  • 无特殊语言。我对通用算法感兴趣,而不是特定的实现。
+1

当然,最好的方法是将这些信息与数据一起存储。 OS X使用[UTI](http://en.wikipedia.org/wiki/Uniform_Type_Identifier)执行此操作。但我认为这没有帮助? – You

回答

1

的回答你的问题很可能只是“正则表达式”如你所要求的算法,而不是工具。实际上,在文件中寻找模式来猜测它的确是最好的方法来决定它是什么。如果有疑问,您可以查看文件扩展名(如果可用),但不应该依赖它。例如,在UNIX系统上,操作系统在决定是否可以执行文件时不关心文件扩展名。所以文件扩展名不应该依赖。

从算法的角度来看,任务本身是微不足道的:收集标识不同文件类型的正则表达式。但是这样做很多工作,对于每一种你想要认识的文件类型,你都需要熟悉它的设计,以便能够写出一个真正能够识别文件类型的表达式,并且只有最少的误报和漏报。

那么为什么要打扰并试图解决其他人已经投入巨资的问题呢?正如您可能知道的那样,最普遍的解决方案是UNIX工具file及其库libmagic,它可以轻松地在您的程序中使用。存在对最常见脚本语言的绑定。 file实用程序的“魔术”数据库可能是最全面的,它知道以前从未听说过的奇特文件类型(因为它们已经被广泛使用了数年或数十年),并且已经调整并修复了很长时间现在是时候了(现在38岁了)。

+0

“知道以前从未听说过的奇特文件类型(因为它们已经被广泛使用了数年或数十年)”的一个潜在缺点是,你正在浪费大量资源用于没有实际用途的东西。这种情况与ncurses terminfo数据库非常相似,99.99%或更多的数据永远不会被普通人使用。 :-) –