如何在java中识别zip文件?

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

 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文件时出错

我建议打开一个简单的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,抛弃它并构造一个新的? 这样您就会丢失原始exception中的所有信息,从而难以调试并理解究竟出了什么问题。 要么根本不抓住它,要么必须包装它,做正确的事:

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

排除exception

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

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

  PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.zip"); boolean extensionCorrect = matcher.matches(path); 
 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

合并nanda和bratkartoffel的答案。 使用apache commons-io安全地关闭文件。

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