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

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

有帮助吗?

解决方案

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

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

最有趣的课程是 javax.activation.MimeType - 实际的 MIME 类型持有者 - 以及 javax.activation.MimetypesFileTypeMap - 其实例可以将 MIME 类型解析为文件的 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);

阿帕奇蒂卡 你只需要 三行代码:

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 了解更多信息。

阿帕奇蒂卡 提供 蒂卡核心 基于流前缀中的魔术标记的 MIME 类型检测。 tika-core 不获取其他依赖项,这使得它与当前未维护的一样轻量级 Mime 类型检测实用程序.

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

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

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

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

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

罗塞因迪亚:

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

如果你被 java 5-6 困住了 那么这个实用程序类来自 伺服开源产品.

你只需要这个功能

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

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

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

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

我尝试过 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();
}

捐出我的 5 美分:

TL,博士

我用 Mimetypes文件类型映射 并将任何不存在且我特别需要的 mime 添加到 mime.types 文件中。

现在,长读:

首先,MIME类型列表是 巨大的, , 看这里: https://www.iana.org/assignments/media-types/media-types.xhtml

我喜欢首先使用 JDK 提供的标准设施,如果这不起作用,我会去寻找其他东西。

根据文件扩展名确定文件类型

从 1.6 开始,Java 有了 MimetypesFileTypeMap,正如上面答案之一所指出的,它是确定 mime 类型的最简单方法:

new MimetypesFileTypeMap().getContentType( fileName );

在其普通实现中,这并没有做太多事情(即它适用于 .html,但不适用于 .png)。然而,添加您可能需要的任何内容类型非常简单:

  1. 在项目的 META-INF 文件夹中创建名为“mime.types”的文件
  2. 为您需要的每种 mime 类型添加一行,但默认实现未提供(有数百种 mime 类型,并且列表随着时间的推移而增长)。

png 和 js 文件的示例条目如下:

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.probeContentType(Paths.get("either file name or full path goes here"));

API 定义提供了支持根据文件名或文件内容(魔字节)确定文件 MIME 类型的功能。因此 探针内容类型() 如果此 API 的实现使用提供给它的 Path 来实际尝试打开与其关联的文件,则该方法会抛出 IOException。

再次,香草 执行 这个(JDK 附带的)还有很多不足之处。

在遥远的星系中的某个理想世界中,所有这些试图解决此文件到 mime 类型问题的库都将简单地实现 java.nio.file.spi.FileTypeDetector, ,您可以将首选实现库的 jar 文件放入您的类路径中,就这样了。

在现实世界中,当你需要 TL,DR 部分时,你应该找到名称旁边星星最多的库并使用它。对于这种特殊情况,我(还不需要;))。

我尝试了几种方法来做到这一点,包括@Joshua Fox 所说的第一种方法。但有些无法识别常见的 mimetypes,例如 PDF 文件,而其他文件则无法信任假文件(我尝试使用扩展名为 TIF 的 RAR 文件)。我找到的解决方案,正如 @Joshua Fox 以肤浅的方式所说的那样,是使用 MimeUtil2, , 像这样:

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

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

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

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

在春天 多部分文件 文件;

org.springframework.web.multipart.MultipartFile

file.getContentType();

这是我发现的最简单的方法:

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'

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

您只需一行即可完成: MimetypesFileTypeMap().getContentType(new File("filename.ext")). 。看完整的测试代码(Java 7):

import java.io.File;
import javax.activation.MimetypesFileTypeMap;
public class MimeTest {
    public static void main(String a[]){
         System.out.println(new MimetypesFileTypeMap().getContentType(
           new File("/path/filename.txt")));
    }
}

此代码产生以下输出: 文本/纯文本

File file = new File(PropertiesReader.FILE_PATH);
MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
String mimeType = fileTypeMap.getContentType(file);
URLConnection uconnection = file.toURL().openConnection();
mimeType = uconnection.getContentType();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top