Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在java中识别zip文件?_Java_Archive_Identification - Fatal编程技术网

如何在java中识别zip文件?

如何在java中识别zip文件?,java,archive,identification,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();

我想确定我的存档是
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文件时出错


异常在行中抛出

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

 PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.zip");
 boolean extensionCorrect = matcher.matches(path); 
您可以在下面的链接中看到它。

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

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

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

  • 50 4B 03 04
  • 50 4B 05 06(空存档)
  • 50 4B 07 08(跨归档)
资料来源:

另一点,请看一下您的代码:

为什么你抓住了死亡无效的例外,扔掉它,然后构建一个新的?这样,您将丢失原始异常中的所有信息,从而难以调试和理解到底出了什么问题。要么根本抓不住它,要么,如果你必须把它包起来,就把它做好:

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

将nanda和Bratkartofel的答案合并在一起

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

添加到对话中

在Java8中,有一个名为的方法也可以工作

以下是一个例子:

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

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

    throw new NotZipFileException();
}

获取文件名。将文件名拆分为。接分机。检查扩展名是rar还是zip。@Ravindrababu-是什么阻止了一个人简单地将非zip文件的扩展名更改为zip或rar?部分正确,可以有3个不同的签名,而不仅仅是一个。
probe
有点夸大了它:内容通常被忽略,标准的实现似乎关注文件扩展名或文件系统设置。有时可能有用,但这不是我想要的!更好地使用InputStream,因为它处理更一般的输入,不是吗?
String contentType = Files.probeContentType(Paths.get(pathToFile);

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

    throw new NotZipFileException();
}