在 Java 中确定 Zip 存档中文件的内容类型

Posted

技术标签:

【中文标题】在 Java 中确定 Zip 存档中文件的内容类型【英文标题】:Determine Content Type of Files in Zip Archive in Java 【发布时间】:2012-11-09 07:12:21 【问题描述】:

使用的环境是 Google App Engine。 zip 文件已上传到 BlobStore。

我有以下代码:

ZipInputStream zis = ...
ZipEntry ze = zis.getNextEntry();
while( ze != null)
    System.out.println(ze.getName());
    ze = zis.getNextEntry();

如何确定 zip 存档中每个文件的内容类型? ze.getName 方法显示文件名。文件类型如何?

谢谢

【问题讨论】:

你可以使用标准的hackish方法从文件名中提取扩展名(lastIndexOf(".")) 嗯,OP 是否不需要其他信息,例如没有扩展名,或者有人弄乱了他们的文件并将“txt”命名为“pdf”?我想只处理 -1 并且名称类似于“SillyFileExtension。”。只需执行与普通文件相同的操作 - 正则表达式? @JRGalia:完全有可能欺骗扩展名,甚至是文件签名,除非该工具非常彻底(不过我怀疑是否存在)。问题是您希望内容类型检测有多接近:基于扩展名或文件签名(内容类型的检测最多取决于我所看到的文件签名)。 【参考方案1】:

您可以使用mime type 而不是尝试通过文件扩展名来猜测,在某些情况下可能会丢失。以下是建立文件mime type 的选项:

    使用javax.activation.MimetypesFileTypeMap,比如:

    System.out.println("Mime Type of " + f.getName() + " is " +
        new MimetypesFileTypeMap().getContentType(f));
    

    使用java.net.URL

    URL u = new URL(fileUrl);
    URLConnection uc = u.openConnection();
    type = uc.getContentType();
    

    使用Apache Tika

    ContentHandler contenthandler = new BodyContentHandler();
    Metadata metadata = new Metadata();
    metadata.set(Metadata.RESOURCE_NAME_KEY, f.getName());
    Parser parser = new AutoDetectParser();
    // OOXMLParser parser = new OOXMLParser();
    parser.parse(is, contenthandler, metadata);
    System.out.println("Mime: " + metadata.get(Metadata.CONTENT_TYPE));
    System.out.println("Title: " + metadata.get(Metadata.TITLE));
    System.out.println("Author: " + metadata.get(Metadata.AUTHOR));
    System.out.println("content: " + contenthandler.toString());
    

    使用JMimeMagic

    MagicMatch match = parser.getMagicMatch(f);
    System.out.println(match.getMimeType()) ;
    

    使用mime-util

    Collection<?> mimeTypes = MimeUtil.getMimeTypes(f);
    

    使用DROID

    Droid (Digital Record Object Identification) is a software tool to 
    perform automated batch identification of file formats.
    

    Aperture 框架

    Aperture is an open source library and framework for crawling and indexing
    information sources such as file systems, websites and mail boxes.
    

有关上述每个选项的更多详细信息,请参阅Get the Mime Type from a File。

在这种情况下,最简单的方法是使用第一个解决方案,javax.activation.MimetypesFileTypeMap,例如:

MimetypesFileTypeMap mtft = new MimetypesFileTypeMap();
String mimeType = mtft.getContentType(ze.getName());
System.out.println(ze.getName()+" type: "+ mimeType);

【讨论】:

我不确定哪一个可以与 ZipEntry 一起使用。 @JRGalia 查看我的更新答案。最简单的方法是使用第一种方法。 它是一个 zip appengine 文件的 ZipEntry。 @Maarten 谢谢,这已经是我在回答中建议的第一个选项:)。 我认为这种方法不适用于ZipEntry(并且测试表明我是对的)。在mtft.getContentType(ze.getName()) 中提供ze.getName() 会使MimetypesFileTypeMap 在光盘上查找它想要读取的具有该名称的文件。但是这样的字段不存在,因为这个名称只是现在在 zip 存档中的文件的原始名称。因此,对于每个文件,我都会得到“application/octet-stream”作为结果。

以上是关于在 Java 中确定 Zip 存档中文件的内容类型的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Java 将每个文件存储在 zip 存档中的数组中?

在 Elixir 中声明 zip 存档内容的最佳方法是啥?

在 Java 中修改 ZIP 存档中的文本文件

在 Java 中提取存档文件 [关闭]

如何在 Windows 批处理文件中使用 7zip 从 ZIP 存档中提取最后一个目录?

PHP Zip:提取目录的内容