2012-11-06 98 views
0

我偶爾會在我的應用程序中收到.zip文件,它會拋出start of central directory not found; zipfile corrupt.異常。這些壓縮文件在我的Mac Finder中打開得很好。是否有可以修復文件的Java zip庫,àla zip -FF?

我可以修復這些文件在命令行中每一次,使用zip -FF bad.zip --out good.zip

任何Java ZIP庫都可以在那裏完成同樣的事情?

+0

的7-Zip [LZMA SDK(HTTP:// www.7-zip.org/sdk.html)在這裏可能很有用。 – Vulcan

回答

1

您可能只想讓Java執行此命令,因爲嚴格來說,zip更像是一個容器,它可以包含不同的壓縮算法。

一般來說,用程序化方法調查和解決與壓縮檔案有關的問題很可能是一項棘手而長期的任務。

Try this與您的命令。

+0

我最初也是這麼想的,但該命令可能不適用於所有操作系統。 – Vulcan

+0

他只使用1個特定的操作系統,其他選項是處理所有可能的算法,實現和zip容器的規格,或者使用壓縮存檔的優秀SDK。 – user1797612

0

有兩種方法可以在Java中使用ZipFile類或使用ZipInputStream打開ZIP文件。

據我所知,ZipFile首先讀取壓縮文件的中央目錄 - 它可以這樣做,因爲它使用下面的RandomAccessFile。但是,ZipInputStream使用內嵌條目信息,如果中央目錄(我認爲該文件存在於該文件的末尾)丟失或損壞,這可能會更好。

因此,通過使用ZipInputStream讀取ZIP文件並使用ZipOutputStream將其寫回到另一個文件,可以在Java中「修復」ZIP文件,並在它們之間複製條目信息。如果ZipInputStream的最後一個條目被截斷,您最終可能會從中讀取IO異常,但它仍然可以保存文件中的其他條目。

0

我試過使用ZipInputStream和ZipOutputStream。但是在執行「getNextEntry()」時,ZipInputStream總是失敗。基本上的代碼下面幾行「getNextEntry()」:

... 
    if ((entry = readLOC()) == null) { 
     return null; 
    } 
... 

一些條目後返回null,我不能再獲得。

但最後我能解決使用的ZipFile與ZipOutputStream在一起,因爲ZipFile中讀到的所有拉鍊條目沒有問題和解決方案看起來像這樣的問題:

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