如何使用Java从文件获取媒体类型(MIME类型)? 我已经尝试了JMimeMagic和Mime-Util。第一个给了我内存异常,第二个没有正确关闭其流。
你将如何探测文件以确定其实际类型(不仅基于扩展名)?
如何使用Java从文件获取媒体类型(MIME类型)? 我已经尝试了JMimeMagic和Mime-Util。第一个给了我内存异常,第二个没有正确关闭其流。
你将如何探测文件以确定其实际类型(不仅基于扩展名)?
Files.probeContentType(path)
。很遗憾,
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
实例应支持标记)。 - Yuriy NakonechnyyURLConnection
识别的内容类型非常有限。例如,它无法检测 application/pdf
。 - kpentchevguessContentTypeFromName()
дҪҝз”Ёй»ҳи®Өзҡ„$JAVA_HOME/lib/content-types.properties
ж–Ү件гҖӮжӮЁеҸҜд»ҘйҖҡиҝҮжӣҙж”№зі»з»ҹеұһжҖ§System.setProperty("content.types.user.table","/lib/path/to/your/property/file");
жқҘж·»еҠ иҮӘе·ұзҡ„жү©еұ•ж–Ү件гҖӮ - Govinnage Rasika Perera使用 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)
查看apidocs获取更多信息。
new Tika().detect(file.toPath())
,而不是基于文件内容的检测。 - Ilya Serbisnew Tika().detect(file.getPath())
,它只使用文件扩展名。 - delucasvbJAF API是JDK 6的一部分。请查看javax.activation
包。
最有趣的类是javax.activation.MimeType
- 实际的MIME类型持有者,以及javax.activation.MimetypesFileTypeMap
- 其实例可以为文件解析MIME类型为字符串:
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);
getContentType(File)
的 Javadoc 表明:返回文件对象的 MIME 类型。该类中的实现调用 getContentType(f.getName())
。 - MatyasMimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(file)
来避免创建一个新的对象。 - akostadinovapplication/octet-stream
)。 - Dmitriy PopovApache Tika提供了基于流前缀魔数的MIME类型检测,tika-core在此方面有所表现。 tika-core
不会获取其他依赖项,这使得它像当前未维护的Mime Type Detection Utility一样轻巧。
以下是一个简单的Java 7代码示例,使用变量theInputStream
和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/1.24/detection.html。If you're an Android developer, you can use a utility class android.webkit.MimeTypeMap
which maps MIME-types to file extensions and vice versa.
Following code snippet may help you.
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");
// 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();
}
ContentInfo
的其他方法(如getMessage()
)来检查它。 - keivan shirkoubian如果你被卡在Java 5-6上,那么可以使用这个来自servoy开源产品的实用类:MimeTypes.java。
你只需要这个函数。
public static String getContentType(byte[] data, String name)
它探查内容的前几个字节并根据这些内容而不是文件扩展名返回内容类型。
为了贡献我的意见:
简短概括
我使用 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 );
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"));