当前位置:  开发笔记 > 编程语言 > 正文

在Java中获取文件的Mime类型

如何解决《在Java中获取文件的Mime类型》经验,为你挑选了10个好方法。

我只是想知道大多数人如何从Java中的文件中获取mime类型?到目前为止,我已经尝试了两个工具:JMimeMagic&Mime-Util.

第一个给了我内存异常,第二个没有正确关闭它的流.我只是想知道是否有其他人有他们使用和正常工作的方法/库?



1> Chris Mowfor..:

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


请注意,Files.probeContentType(Path)在多个操作系统上都存在错误,并且已经提交了大量错误报告.我在使用ubuntu但在Windows上失败的软件时遇到了问题.似乎在Windows上Files.probeContentType(Path)总是返回null.这不是我的系统所以我没有检查JRE或Windows版本.它可能是用于Java 7的oracle JRE的Windows 7或8.
这方面的一个主要限制是该文件必须存在于文件系统上.这不适用于流或字节数组等.
我在OS X 10.9上运行,并且我为`.xml`,`.png`和`.xhtml`文件获取`null`.我不知道我是在做一些可怕的错误,但这看起来相当可怕.
如果文件的扩展名丢失或错误,这将无用.
当我从名称中删除扩展名时,此方法无法返回mime类型.例如,如果名称为test.mp4,我将其更改为"test",方法返回null.同时我将电影扩展名更改为png等,它返回png mime类型

2> Joshua Fox..:

不幸,

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

不起作用,因为这种URL的使用会使文件被锁定,因此,例如,它是不可删除的.

但是,你有这个:

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

以及以下内容,其优点是不仅仅使用文件扩展名,还可以查看内容

InputStream is = new BufferedInputStream(new FileInputStream(file));
mimeType = URLConnection.guessContentTypeFromStream(is);
 //...close stream

但是,正如上面的评论所暗示的那样,内置的mime类型表非常有限,不包括例如MSWord和PDF.所以,如果你想要概括,你需要超越内置库,使用例如Mime-Util(这是一个很棒的库,同时使用文件扩展名和内容).


完美的解决方案 - 帮助了我很多!将`FileInputStream`包装到`BufferedInputStream`中是至关重要的部分 - 否则`guessContentTypeFromStream`返回`null`(传递`InputStream`实例应该支持标记)
Howerver,`URLConnection`有一组非常有限的内容类型,它确实可以识别.例如,它无法检测到`application/pdf`.
它只会让它锁定,因为你没有办法将它关闭.断开URLConnection将解锁它.
`guessContentTypeFromName()`使用默认的`$ JAVA_HOME/lib/content-types.properties`文件.您可以通过更改系统属性`System.setProperty("content.types.user.table","/ lib/path/to/your/property/file")来添加自己的扩展文件;`

3> Adam Hošek..:

JAF API是JDK 6的一部分.查看javax.activation包.

最有趣的类是javax.activation.MimeType- 一个实际的MIME类型持有者 - 和javax.activation.MimetypesFileTypeMap- 类,其实例可以将MIME类型解析为文件的String:

String fileName = "/path/to/file";
MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();

// only by file name
String mimeType = mimeTypesMap.getContentType(fileName);

// or by actual File instance
File file = new File(fileName);
mimeType = mimeTypesMap.getContentType(file);


你可以通过`MimetypesFileTypeMap.getDefaultFileTypeMap()跳过创建一个新对象.getContentType(file)`
不幸的是,由于`getContentType(File)`的javadoc表示:_返回文件对象的MIME类型.此类中的实现调用`getContentType(f.getName())`._
请记住,您可以使用META-INF/mime.types文件扩展此功能,因此如果您被迫使用Java 6,它是完美的.http://docs.oracle.com/javaee/5/api/javax/activation/MimetypesFileTypeMap html的

4> lifeisfoo..:

使用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)

请记住,它的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)

有关更多信息,请参阅apidocs.



5> koppor..:

Apache Tika在tika-core中提供基于流前缀中的魔术标记的mime类型检测.tika-core不会获取其他依赖项,这使得它与当前未维护的Mime类型检测实用程序一样轻量级.

简单的代码示例(Java 7),使用变量theInputStreamtheFileName

try (InputStream is = theInputStream;
        BufferedInputStream bis = new BufferedInputStream(is);) {
    AutoDetectParser parser = new AutoDetectParser();
    Detector detector = parser.getDetector();
    Metadata md = new Metadata();
    md.add(Metadata.RESOURCE_NAME_KEY, theFileName);
    MediaType mediaType = detector.detect(bis, md);
    return mediaType.toString();
}

请注意,MediaType.detect(...)不能直接使用(TIKA-1120).https://tika.apache.org/0.10/detection.html提供了更多提示.



6> Pawan..:

如果您是Android开发人员,则可以使用android.webkit.MimeTypeMap将MIME类型映射到文件扩展名的实用程序类,反之亦然.

以下代码段可能会对您有所帮助.

private static String getMimeType(String fileUrl) {
    String extension = MimeTypeMap.getFileExtensionFromUrl(fileUrl);
    return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}


如果尝试使用本地文件路径(例如"/sdcard/path/to/video.extension"),这也有效.问题是如果本地文件的路径中包含空格,它总是返回null

7> AlikElzin-ki..:

来自roseindia:

FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimeType = fileNameMap.getContentTypeFor("alert.gif");


无论谁投票给答案,请添加评论,以便我(和其他人)可以学习发布更好的答案.
功能很不完整.从Java 7开始,html,pdf和jpeg扩展返回正确的mime类型,但js和css返回null!
我没有投票给你,但getFileNameMap不适用于许多基本文件类型,例如'bmp'.URLConnection.guessContentTypeFromName也返回相同的内容

8> Ovidiu Bulig..:

如果您遇到java 5-6那么这个实用程序类来自servoy开源产品.

你只需要这个功能

public static String getContentType(byte[] data, String name)

它探测内容的第一个字节,并根据该内容而不是文件扩展名返回内容类型.



9> Gray..:

我只是想知道大多数人如何从Java中的文件中获取mime类型?

我发布了我的SimpleMagic Java包,它允许从文件和字节数组中确定内容类型(mime类型).它旨在读取和运行Unix文件(1)命令魔术文件,这些文件是大多数Unix操作系统配置的一部分.

我尝试过Apache Tika但是它有很多依赖,URLConnection它不使用文件的字节,MimetypesFileTypeMap也只是查看文件名.

使用SimpleMagic,您可以执行以下操作:

// create a magic utility using the internal magic file
ContentInfoUtil util = new ContentInfoUtil();
// if you want to use a different config file(s), you can load them by hand:
// ContentInfoUtil util = new ContentInfoUtil("/etc/magic");
...
ContentInfo info = util.findMatch("/tmp/upload.tmp");
// or
ContentInfo info = util.findMatch(inputStream);
// or
ContentInfo info = util.findMatch(contentByteArray);

// null if no match
if (info != null) {
   String mimeType = info.getMimeType();
}



10> nidalpres..:

用我的5美分筹码:

TL,DR

我使用MimetypesFileTypeMap并将任何不存在的mime添加到mime.types文件中,我特别需要它.

现在,长读:

首先,MIME类型列表很大,请参见:https://www.iana.org/assignments/media-types/media-types.xhtml

我想首先使用JDK提供的标准工具,如果这不起作用,我会去寻找其他东西.

从文件扩展名确定文件类型

从1.6开始,Java有MimetypesFileTypeMap,如上面的一个答案中所指出的,它是确定mime类型的最简单方法:

new MimetypesFileTypeMap().getContentType( fileName );

在它的vanilla实现中,这没有太大作用(即它适用于.html但不适用于.png).但是,添加您可能需要的任何内容类型非常简单:

    在项目的META-INF文件夹中创建名为"mime.types"的文件

    为你需要的每个mime类型添加一行,默认实现不提供(有数百种mime类型,列表随着时间的推移而增长).

png和js文件的示例条目是:

image/png png PNG
application/javascript js

有关mime.types文件格式,请在此处查看更多详细信息:https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html

从文件内容确定文件类型

从1.7开始,Java有java.nio.file.spi.FileTypeDetector,它定义了一个标准API,用于以特定实现的方式确定文件类型.

要获取文件的mime类型,您只需使用Files并在代码中执行此操作:

Files.probeContentType(Paths.get("either file name or full path goes here"));

API定义提供了支持从文件名或文件内容(魔术字节)确定文件mime类型的工具.这就是为什么probeContentType()方法抛出IOException,以防此API的实现使用提供给它的Path来实际尝试打开与之关联的文件.

同样,vanilla的实现(JDK附带的实现)还有很多不足之处.

在遥远的银河系中的一些理想世界中,所有这些试图解决这个文件到mime类型问题的库只会实现java.nio.file.spi.FileTypeDetector,你会放入首选的实现库的jar将文件存入您的类路径,就可以了.

在现实世界中,你需要TL,DR部分,你应该找到其名称旁边有大多数星星的图书馆并使用它.对于这种特殊情况,我不需要一个(还有)).

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有