java 如何在java中识别zip文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33934178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 22:18:42  来源:igfitidea点击:

How to identify a zip file in java?

javaarchiveidentification

提问by Hyman

I want to identify my archive whether it is zipor rar. But the problem I get runtime error before I can validate my file. I want to create custom notification:

我想确定我的档案是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");
    }
  }
}

At the moment I have runtime error:

目前我有运行时错误:

java.util.zip.ZipException: error in opening zip file

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

回答by bratkartoffel

I'd suggest to open a plain InputStream an reading the first few bytes (magic bytes) and not to rely on the file extension as this can be easily spoofed. Also, you can omit the overhead creating and parsing the files.

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

For RAR the first bytes should be 52 61 72 21 1A 07.

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

For ZIP it should be one of:

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

  • 50 4B 03 04
  • 50 4B 05 06(empty archive)
  • 50 4B 07 08(spanned archive).
  • 50 4B 03 04
  • 50 4B 05 06(空存档)
  • 50 4B 07 08(跨存档)。

Source: https://en.wikipedia.org/wiki/List_of_file_signatures

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

Another point, just looked at your code:

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

Why do you catch die InvalidZipException, throw it away and construct a new one? This way you lose all the information from the original exception, making it hard to debug and understand what exactly went wrong. Either don't catch it at all or, if you have to wrap it, do it right:

为什么你会捕捉到 InvalidZipException,扔掉它并构建一个新的?这样,您会丢失原始异常中的所有信息,从而难以调试和了解究竟出了什么问题。要么根本不抓住它,要么,如果必须包装它,请正确处理:

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

回答by Fabian Braun

Merging the answers of nanda & bratkartoffel.

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

回答by nanda

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");

You can see it in the following link. http://www.coderanch.com/t/381509/java/java/check-file-zip-file-java

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

回答by hatze

Exception is thrown in line

异常被抛出

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

That's because if a non-ZipFile is given as parameter for the ZipFileconstructor the ZipExceptionis thrown. So you have to check beforegenerating a new ZipFileObject if your file path points to a correct ZipFile. One solution might be to check the extension of the file path like so

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

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