如何获取文件的媒体类型(MIME类型)?

11 浏览
0 Comments

如何获取文件的媒体类型(MIME类型)?

如何使用Java从文件中获取媒体类型(MIME类型)?到目前为止,我尝试过JMimeMagic和Mime-Util。第一个给我带来了内存异常,第二个没有正确关闭流。

你会如何探测文件以确定其实际类型(不仅仅基于扩展名)?

0
0 Comments

如何获取文件的媒体类型(MIME类型)?

在使用Apache Tika时,你只需要三行代码:

File file = new File("/path/to/file");
Tika tika = new Tika();
System.out.println(tika.detect(file));

如果你有一个Groovy控制台,只需粘贴并运行以下代码来进行测试:

@Grab('org.apache.tika:tika-core:1.14')
import org.apache.tika.Tika;
def tika = new Tika()
def file = new File("/path/to/file")
println tika.detect(file)

请记住,Tika的API非常丰富,它可以解析“任何”类型的文件。截至tika-core 1.14版本,你可以使用以下方法:

String detect(byte[] prefix)
String detect(byte[] prefix, String name)
String detect(File file)
String detect(InputStream stream)
String detect(InputStream stream, Metadata metadata)
String detect(InputStream stream, String name)
String detect(Path path)
String detect(String name)
String detect(URL url)

请查看[官方文档](http://tika.apache.org/1.14/api/)获取更多信息。

关于Tika的一个不好的地方是依赖项过多,它使我的JAR文件增加了54MB的大小!

1.17版本是独立的,只有648KB。

如果你只想根据文件扩展名进行检测,而不是根据文件内容进行检测,你可以使用以下代码:

new Tika().detect(file.toPath())

文档中说仍然使用文档内容。我认为你指的是`new Tika().detect(file.getPath())`,它只会使用文件的扩展名进行检测。

0
0 Comments

如何获取文件的媒体类型(MIME类型)?

不幸的是,

mimeType = file.toURL().openConnection().getContentType();

不起作用,因为这种使用URL的方式会锁定文件,例如,无法删除文件。

然而,您可以使用以下方式:

mimeType= URLConnection.guessContentTypeFromName(file.getName());

还有以下方法,它不仅仅使用文件扩展名,还会查看内容,具有优势:

InputStream is = new BufferedInputStream(new FileInputStream(file));
mimeType = URLConnection.guessContentTypeFromStream(is);
//...关闭流

然而,正如上面的注释所建议的那样,内置的mime类型表相当有限,例如不包括MSWord和PDF。因此,如果您想进行泛化,就需要超越内置的库,例如使用Mime-Util(这是一个很棒的库,同时使用文件扩展名和内容)。

完美的解决方案-对我帮助很大!将FileInputStream包装成BufferedInputStream是关键部分-否则guessContentTypeFromStream将返回null(传递的InputStream实例应支持标记)。

然而,URLConnection的内容类型识别能力非常有限。例如,它无法检测application/pdf

它可以检测到pdf文件。但它无法检测到办公文件,例如*.doc。

它之所以被锁定,是因为您没有关闭它的方法。断开URL连接将解锁它。

无论是guessContentTypeFromStream还是guessContentTypeFromName都无法识别例如mp4。

guessContentTypeFromName()使用默认的$JAVA_HOME/lib/content-types.properties文件。您可以通过更改系统属性System.setProperty("content.types.user.table","/lib/path/to/your/property/file");来添加自己的扩展文件。

它无法检测.js和.css文件。是否有其他方法可以检测这些文件?

有关Mime-Util的任何链接吗?我在github上找到了这个项目,但没有任何描述:(

guessContentTypeFromName使用了synchronized FileNameMap getFileNameMap,在多线程中祝你好运。

0
0 Comments

如何获取文件的媒体类型(MIME类型)?

在Java 7中,您现在可以使用Files.probeContentType(path)来实现。

这对我非常有帮助,因为mime-util网站似乎已经关闭,我无法确定该库是否正在维护!

这个方法运行良好,但是我没有找到一种方法来添加更多我理解的文件类型。例如,ISO镜像返回null,.zip归档文件以及ini配置文件也返回null。

.garriss给了我更多的积分,比我给出的任何其他答案都多!真疯狂,不是吗? 🙂

请注意,Files.probeContentType(Path)在几个操作系统上存在缺陷,许多错误报告已经提交。我在ubuntu上遇到了一个问题,软件在windows上失败了。似乎在windows上,Files.probeContentType(Path)总是返回null。这不是我的系统,所以我没有检查JRE或者windows的版本。它可能是windows 7或8,可能使用了oracle的java 7的JRE。

我在OS X 10.9上运行,对于.xml、.png和.xhtml文件,我得到了null。我不知道我是否做错了什么,但这似乎相当糟糕。

如果文件没有扩展名,我无法成功地让它工作。

在类似*nix的系统上,似乎默认的文件类型检测器只返回null,而且用户必须手动添加一个或多个检测器实现,这似乎并不是很简单。所以至少对于我所需要的用例来说,即将文件扩展名映射到mime类型的简单方法,这个解决方案不起作用。

这个方法的一个重要限制是文件必须存在于文件系统中。它不能用于流或者字节数组等。

更奇怪的是,我有两台windows 8.1的笔记本电脑,其中一台在调用zip文件时得到application/x-zip-compressed,而另一台得到null。完全不可靠:\.那么,假设我希望我的应用程序根据文件的编码方案进行切换(比如说我的应用程序接受XML和JSON配置),而文件只是叫做“configuration”(没有扩展名),最可靠的方法是确定该文件的类型,有点作弊和读取几个字节吗?

如果我去掉文件名的扩展名,这个方法就无法返回mime类型。例如,如果文件名是test.mp4,我将其改为“test”,这个方法就会返回null。而且我将电影扩展名改为png等,它将返回png mime类型。

如果文件缺少或错误的扩展名,这就是无用的。

基于Linux的实现似乎使用Linux /usr/bin/file,这是好的,除非有一个扩展名,否则它将不再深入查看,这是不好的。如果将XML文件重命名为.json,它会告诉您它是JSON。输入垃圾,输出垃圾。除非您对文件数据非常确定,否则您真的不想相信这种方法。

获得Path对象的方法是使用Paths.get(str)。

在Windows上,它只使用扩展名来确定文件类型。在Linux上,直到Java 8,它使用了一堆探测器:基于Gnome I/O、Gnome VFS和libmagic库的基于内容的探测器以及基于扩展名的探测器,通过/etc/mime.types实现。但是从Java 9开始,JDK中移除了所有基于内容的探测器(1,2),只剩下了基于扩展名的探测器用于Linux。所以如果您的文件没有扩展名,这个方法将始终返回null 🙁

JDK中的默认实现是通过文件扩展名进行探测,添加github.com/overview/mime-types作为依赖,它将通过SPI使用它,然后通过魔术数字进行探测。

0