如何使用Java从文件中获得媒体类型(MIME类型)?到目前为止,我已经尝试了JMimeMagic和Mime-Util。第一个给了我内存异常,第二个没有正确地关闭它的流。

您将如何探测该文件以确定其实际类型(而不仅仅是基于扩展名)?


当前回答

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

其他回答

JAF API是JDK 6的一部分。看看javax。激活包。

最有趣的类是javax.activation.MimeType -一个实际的MIME类型holder -和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);
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;
}

不幸的是,

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-types的内置表是非常有限的,例如,不包括MSWord和PDF。因此,如果您想要泛化,您将需要使用内置库,例如Mime-Util(这是一个很棒的库,同时使用文件扩展名和内容)。

如果你正在使用Servlet并且Servlet上下文对你可用,你可以使用:

getServletContext().getMimeType( fileName );

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