我偶尔会在我的应用中收到抛出start of central directory not found;
zipfile corrupt.
个例外的.zip文件。这些zip文件在Mac的Finder中打开很好。
我可以使用zip -FF bad.zip --out good.zip
那里的任何Java ZIP库都能完成同样的事情吗?
答案 0 :(得分:1)
您可能只想让Java执行此命令,因为严格来说,zip更像是一个容器,它可以包含不同的压缩算法。
一般来说,使用程序化方法调查和解决与压缩档案相关的问题,这可能是一项棘手而漫长的任务。
用你的命令答案 1 :(得分:0)
有两种方法可以使用ZipFile类或使用ZipInputStream在Java中打开ZIP文件。
据我所知,ZipFile
首先读取zip文件的中心目录 - 它可以执行此操作,因为它使用下面的RandomAccessFile
。但是,ZipInputStream
使用内联条目信息,如果我认为存在于文件末尾的中心目录丢失或损坏,这可能会更好。
因此,有可能通过使用ZipInputStream读取ZIP文件并使用ZipOutputStream将其写回另一个文件,在它们之间复制条目信息来“修复”Java中的ZIP文件。如果ZipInputStream被截断,您最终可能会从ZipInputStream的最后一个条目读取IO异常,但它仍然可以保存文件中的其他先前条目。
答案 2 :(得分:0)
我尝试使用ZipInputStream和ZipOutputStream。但ZipInputStream在执行某些操作时始终失败:“getNextEntry()”。基本上是“getNextEntry()”中的以下代码行:
...
if ((entry = readLOC()) == null) {
return null;
}
...
在一些条目后返回null,我无法进一步。
但最后我可以使用ZipFile与ZipOutputStream一起解决问题,因为ZipFile正在读取所有zip条目而没有问题,解决方案如下所示:
protected void repairZipFile(String file) throws IOException {
File repairZipFile = new File(file+".repair");
ZipFile zipFile = new ZipFile(file);
Enumeration<? extends ZipEntry> zipFileEntries = zipFile.entries();
InputStream zis;
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(repairZipFile));
byte[] b = new byte[1024];
while(zipFileEntries.hasMoreElements()){
ZipEntry zipEntry = zipFileEntries.nextElement();
zos.putNextEntry(zipEntry);
zis = zipFile.getInputStream(zipEntry);
int n = zis.read(b);
while(n>=0) {
zos.write(b, 0, n);
n = zis.read(b);
}
zis.close();
zos.closeEntry();
}
zipFile.close();
zos.flush();
zos.close();
Files.move(repairZipFile.toPath(), (new File(file)).toPath(), StandardCopyOption.REPLACE_EXISTING);
}