在Java中获取文件的MIMEtypes
我只是想知道大多数人从Java文件中获取MIMEtypes? 到目前为止,我已经尝试了两个utils: JMimeMagic
& Mime-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),使用variablestheFileName
和theFileName
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开源的产品
你只需要这个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非常简单:
- 在您的项目的META-INF文件夹中创build名为“mime.types”的文件
- 为每个需要的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; }