提问者:小点点

如何识别java中的zip文件?


我想识别我的存档是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.zipZipException:打开zip文件时出错


共3个答案

匿名用户

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

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

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

  • 504B03 04
  • 504B05 06(空存档)
  • 504B07 08(跨度存档)。

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

还有一点,只是看了你的代码:

为什么要捕获die InvalidZipException,扔掉它并构造一个新的异常?这样你就会丢失原始异常的所有信息,使得调试和理解到底出了什么问题变得困难。要么根本不捕获它,要么,如果你必须包装它,做对:

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

匿名用户

合并南达的答案

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;
}

匿名用户

异常是在线抛出的

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

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

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