如何在java中识别zip文件?

时间:2015-11-26 08:55:00

标签: java archive identification

我想确定我的档案是zip还是rar。但是在我可以验证我的文件之前,我遇到运行时错误的问题。我想创建自定义通知:

public class ZipValidator {
  public void validate(Path pathToFile) throws IOException {
    try {
      ZipFile zipFile = new ZipFile(pathToFile.toFile());
      String zipname = zipFile.getName();
    } catch (InvalidZipException e) {
      throw new InvalidZipException("Not a zip file");
    }
  }
}

目前我有运行时错误:

  

java.util.zip.ZipException:打开zip文件时出错

5 个答案:

答案 0 :(得分:11)

我建议打开一个简单的InputStream,读取前几个字节(魔术字节),而不是依赖文件扩展名,因为这很容易被欺骗。此外,您可以省略创建和解析文件的开销。

对于RAR,第一个字节应为 52 61 72 21 1A 07

对于ZIP,它应该是以下之一:

  • 50 4B 03 04
  • 50 4B 05 06 (空档案)
  • 50 4B 07 08 (跨越档案)。

来源:https://en.wikipedia.org/wiki/List_of_file_signatures

另一点,只看你的代码:

为什么你会死掉InvalidZipException,抛弃它并构造一个新的?这样您就会丢失原始异常中的所有信息,从而难以调试并了解到底出了什么问题。要么根本不抓住它,要么必须包裹它,做正确的事:

} catch (InvalidZipException e) {
  throw new InvalidZipException("Not a zip file", e);
}

答案 1 :(得分:2)

RandomAccessFile raf = new RandomAccessFile(f, "r");

long n = raf.readInt();

raf.close();

if (n == 0x504B0304)

    System.out.println("Should be a zip file");

else

    System.out.println("Not a zip file");

您可以在以下链接中看到它。 http://www.coderanch.com/t/381509/java/java/check-file-zip-file-java

答案 2 :(得分:1)

异常抛出行

ZipFile zipFile = new ZipFile(pathToFile.toFile());

那是因为如果给出非ZipFile作为ZipFile构造函数的参数,则抛出ZipException。 因此,如果您的文件路径指向正确的ZipFile,则必须先检查之前生成新的ZipFile对象。 一种解决方案可能是检查文件路径的扩展名,如此

 PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.zip");
 boolean extensionCorrect = matcher.matches(path); 

答案 3 :(得分:1)

合并nanda&的答案bratkartoffel。

private static boolean isArchive(File f) {
    int fileSignature = 0;
    try (RandomAccessFile raf = new RandomAccessFile(f, "r")) {
        fileSignature = raf.readInt();
    } catch (IOException e) {
        // handle if you like
    }
    return fileSignature == 0x504B0304 || fileSignature == 0x504B0506 || fileSignature == 0x504B0708;
}

答案 4 :(得分:1)

添加到对话中。

在Java 8中,有一种叫做Files.probeContentType(Path path)的方法也应该可以工作。

这里是一个例子:

String contentType = Files.probeContentType(Paths.get(pathToFile);

if (!contentType.equals("application/zip")) {

    throw new NotZipFileException();
}