在 Java 中获取文件的 Mime 类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51438/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:40:29  来源:igfitidea点击:

Getting A File's Mime Type In Java

javamime

提问by Lee Theobald

I was just wondering how most people fetch a mime type from a file in Java? So far I've tried two utils: JMimeMagic& Mime-Util.

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

The first gave me memory exceptions, the second doesn't close its streams off properly. I was just wondering if anyone else had a method/library that they used and worked correctly?

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

采纳答案by Chris Mowforth

In Java 7 you can now just use Files.probeContentType(path).

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

回答by Joshua Fox

Unfortunately,

很遗憾,

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

does not work, since this use of URL leaves a file locked, so that, for example, it is undeletable.

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

However, you have this:

但是,你有这个:

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

and also the following, which has the advantage of going beyond mere use of file extension, and takes a peek at content

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

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

However, as suggested by the comment above, the built-in table of mime-types is quite limited, not including, for example, MSWord and PDF. So, if you want to generalize, you'll need to go beyond the built-in libraries, using, e.g., Mime-Util (which is a great library, using both file extension and content).

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

回答by Adam Ho?ek

The JAF API is part of JDK 6. Look at javax.activationpackage.

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

Most interesting classes are javax.activation.MimeType- an actual MIME type holder - and javax.activation.MimetypesFileTypeMap- class whose instance can resolve MIME type as String for a file:

最有趣的类是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);

回答by AlikElzin-kilaka

From roseindia:

来自玫瑰印度

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

回答by ricardoc

I tried several ways to do it, including the first ones said by @Joshua Fox. But some don't recognize frequent mimetypes like for PDF files, and other could not be trustable with fake files (I tried with a RAR file with extension changed to TIF). The solution I found, as also is said by @Joshua Fox in a superficial way, is to use MimeUtil2, like this:

我尝试了几种方法,包括@Joshua Fox 所说的第一种方法。但是有些人无法识别 PDF 文件等常见的 mimetypes,而其他人则无法信任假文件(我尝试使用扩展名为 TIF 的 RAR 文件)。我发现的解决方案,正如@Joshua Fox 以肤浅的方式所说的,是使用MimeUtil2,如下所示:

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

回答by Pawan

If you're an Android developer, you can use a utility class android.webkit.MimeTypeMapwhich maps MIME-types to file extensions and vice versa.

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

Following code snippet may help you.

以下代码片段可能对您有所帮助。

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

回答by koppor

Apache Tikaoffers in tika-corea mime type detection based based on magic markers in the stream prefix. tika-coredoes not fetch other dependencies, which makes it as lightweight as the currently unmaintained Mime Type Detection Utility.

Apache Tikatika-core 中提供了基于流前缀中的魔术标记的 mime 类型检测。tika-core不获取其他依赖项,这使其与当前未维护的Mime Type Detection Utility一样轻量级。

Simple code example (Java 7), using the variables theInputStreamand theFileName

简单的代码示例(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();
}

Please note that MediaType.detect(...) cannot be used directly (TIKA-1120). More hints are provided at https://tika.apache.org/0.10/detection.html.

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

回答by Gray

I was just wondering how most people fetch a mime type from a file in Java?

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

I've published my SimpleMagicJava package which allows content-type (mime-type) determination from files and byte arrays. It is designed to read and run the Unix file(1) command magic files that are a part of most ~Unix OS configurations.

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

I tried Apache Tika but it is hugewith tons of dependencies, URLConnectiondoesn't use the bytes of the files, and MimetypesFileTypeMapalso just looks at files names.

我尝试过 Apache Tika,但它有大量的依赖项,URLConnection不使用文件的字节,而且MimetypesFileTypeMap只查看文件名。

With SimpleMagic you can do something like:

使用 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();
}

回答by Ovidiu Buligan

If you are stuck with java 5-6then this utility class from servoy open source product.

如果您坚持使用 java 5-6,那么这个来自伺服开源产品的实用程序类。

You only need this function

你只需要这个功能

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

It probes the first bytes of the content and returns the content types based on that content and not by file extension.

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

回答by javacreed

It is better to use two layer validation for files upload.

文件上传最好使用两层验证。

First you can check for the mimeType and validate it.

首先,您可以检查 mimeType 并验证它。

Second you should look to convert the first 4 bytes of your file to hexadecimal and then compare it with the magic numbers. Then it will be a really secure way to check for file validations.

其次,您应该将文件的前 4 个字节转换为十六进制,然后将其与幻数进行比较。那么这将是一种非常安全的检查文件验证的方法。