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

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


当前回答

如果你在linux操作系统上工作,有一个命令行文件——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 "";
}

Then

mimetype("/home/nyapp.war") //  'application/zip'

mimetype("/var/www/ggg/au.mp3") //  'audio/mp3'

其他回答

在Java中,URLConnection类有一个名为guessContentTypeFromName(String fileName)的方法,可以用来根据文件的文件名猜测文件的MIME媒体类型(也称为内容类型)。该方法使用文件名的扩展名来确定内容类型。

String fileName = "image.jpg";
String contentType = URLConnection.guessContentTypeFromName(fileName);
System.out.println(contentType); // "image/jpeg"

想要了解更多,请阅读这篇文章

在尝试了其他各种库之后,我最终选择了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);

我用下面的代码做到了。

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MimeFileType {

    public static void main(String args[]){

        try{
            URL url = new URL ("https://www.url.com.pdf");

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setDoOutput(true);
            InputStream content = (InputStream)connection.getInputStream();
            connection.getHeaderField("Content-Type");

            System.out.println("Content-Type "+ connection.getHeaderField("Content-Type"));

            BufferedReader in = new BufferedReader (new InputStreamReader(content));

        }catch (Exception e){

        }
    }
}

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

不幸的是,

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(这是一个很棒的库,同时使用文件扩展名和内容)。