在Java中获取文件的MIMEtypes

我只是想知道大多数人从Java文件中获取MIMEtypes? 到目前为止,我已经尝试了两个utils: JMimeMagicMime-Util

第一个给我内存exception,第二个不正确closures它的stream。 我只是想知道是否有其他人有一个方法/库,他们使用和正常工作?

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

不幸,

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

不起作用,因为URL的这种使用将文件locking,所以例如它是不可删除的。

不过,你有这个:

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

还有以下几个方面,其优点是不仅仅是使用文件扩展名,而是对内容进行了窥视

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

但是,正如上面的评论所build议的,mimetypes的内置表是相当有限的,不包括例如MSWord和PDF。 所以,如果你想概括一下,你将需要超越内置的库,例如使用Mime-Util(这是一个伟大的库,同时使用文件扩展名和内容)。

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

大多数有趣的类是javax.activation.MimeType – 一个实际的MIMEtypes持有者 – 和javax.activation.MimetypesFileTypeMap – 类的实例可以将MIMEtypesparsing为文件的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); 

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

以下代码片段可以帮助你。

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

从roseindia :

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

Apache Tika在tika-core中提供基于stream前缀中魔术标记的MIMEtypes检测。 tika-core不会获取其他依赖关系,这使得它与当前未维护的Mimetypes检测实用程序一样轻量级。

简单的代码示例(Java 7),使用variablestheFileNametheFileName

 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提供了更多提示。;

使用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是丰富的,它可以parsing“任何东西”。 从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以获取更多信息。

如果你用Java 5-6卡住了,那么这个工具类就是从servoy开源的产品

https://github.com/Servoy/servoy-client/blob/e7f5bce3c3dc0f0eb1cd240fce48c75143a25432/servoy_shared/src/com/servoy/j2db/util/MimeTypes.java#L34

你只需要这个function

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

它探测内容的第一个字节,并返回基于内容的内容types,而不是文件扩展名。

我只是想知道大多数人从Java文件中获取MIMEtypes?

我已经发布了我的SimpleMagic Java包,它允许从文件和字节数组中进行内容types(MIMEtypes)确定。 它被devise为读取和运行Unix文件(1)命令魔术文件,它们是大多数Unix操作系统configuration的一部分。

我尝试了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(); } 

我尝试了几种方法来做到这一点,包括@Joshua Fox所说的第一种方法。 但有些不识别PDF文件等频繁的mimetypes,其他的不可信的假文件(我尝试了一个扩展名改为TIF的RAR文件)。 我发现的解决scheme,也是由@Joshua Fox以肤浅的方式说的,就是使用MimeUtil2 ,就像这样:

 MimeUtil2 mimeUtil = new MimeUtil2(); mimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector"); String mimeType = MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file)).toString(); 

上传文件最好使用两层validation。

首先你可以检查mimeType并validation它。

其次,您应该将文件的前4个字节转换为hex,然后将其与幻数进行比较。 那么这将是一个非常安全的方式来检查文件validation。

这是我find这样最简单的方法:

 byte[] byteArray = ... InputStream is = new BufferedInputStream(new ByteArrayInputStream(byteArray)); String mimeType = URLConnection.guessContentTypeFromStream(is); 

如果你在linux操作系统上,有一个命令行file --mimetype

 String mimetype(file){ //1. run cmd Object cmd=Runtime.getRuntime().exec("file --mime-type "+file); //2 get output of cmd , then //3. parse mimetype if(output){return output.split(":")[1].trim(); } return ""; } 

然后

 mimetype("/home/nyapp.war") // 'application/zip' mimetype("/var/www/ggg/au.mp3") // 'audio/mp3' 

在Spring的MultipartFile文件中;

org.springframework.web.multipart.MultipartFile

file.getContentType();

尝试了其他各种图书馆后,我用mime-util解决了这个问题。

 <groupId>eu.medsea.mimeutil</groupId> <artifactId>mime-util</artifactId> <version>2.1.3</version> </dependency> File file = new File("D:/test.tif"); MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector"); Collection<?> mimeTypes = MimeUtil.getMimeTypes(file); System.out.println(mimeTypes); 

用我的5美分:

TL,DR

我使用MimetypesFileTypeMap并添加任何不在那里的MIME,我特别需要它,进入mime.types文件。

而现在,长阅读:

首先,MIMEtypes列表是巨大的 ,看到这里: https : //www.iana.org/assignments/media-types/media-types.xhtml

我喜欢首先使用JDK提供的标准工具,如果这样做不起作用,我会去寻找别的东西。

从文件扩展名中确定文件types

从1.6开始,Java有MimetypesFileTypeMap,正如上面的答案之一所指出的那样,它是确定MIMEtypes的最简单的方法:

 new MimetypesFileTypeMap().getContentType( fileName ); 

在它的香草实现这并没有太多(即它适用于.html,但它不适用于.png)。 但是,添加您可能需要的任何内容types非常简单:

  1. 在您的项目的META-INF文件夹中创build名为“mime.types”的文件
  2. 为每个需要的MIMEtypes添加一行,默认实现不提供(随着时间的推移,有数百个MIMEtypes和列表增长)。

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

 image/png png PNG application/javascript js 

对于mime.types文件格式,请参阅此处的更多详细信息: https : //docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html

从文件内容中确定文件types

从1.7开始,Java有java.nio.file.spi.FileTypeDetector ,它定义了一个标准的API来确定文件types。

要获取文件的MIMEtypes,只需使用“ 文件” ,然后在代码中执行以下操作:

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

API定义提供了支持从文件名或文件内容(魔术字节)中确定文件MIMEtypes的function。 这就是为什么probeContentType()方法会抛出IOExceptionexception,以防API的实现使用提供给它的Path实际尝试打开与之关联的文件。

再一次,这个(JDK自带的)的实现离开了很多地方。

在很远的一个银河系的理想世界里,所有这些试图解决这个文件到MIMEtypes问题的库都会简单地实现java.nio.file.spi.FileTypeDetector ,你可以放入首选的实现库的jar文件到你的类path,就是这样。

在现实世界中,你需要TL,DR部分,你应该find它的名字旁边大部分星星的图书馆和使用它。 对于这个特殊情况,我不需要一个(但;))。

 public String getFileContentType(String fileName) { String fileType = "Undetermined"; final File file = new File(fileName); try { fileType = Files.probeContentType(file.toPath()); } catch (IOException ioException) { System.out.println( "ERROR: Unable to determine file type for " + fileName + " due to exception " + ioException); } return fileType; } 
Interesting Posts