2013-08-06 52 views
2

我試圖創建一個方法,只需一步就可以將多個zip壓縮文件合併到eachother中。該代碼看起來非常好,它應該工作。但是當我運行它時,我得到了一個非常奇怪的例外:Java - 意外的ZipException(意想不到的錯誤類型)

java.lang.RuntimeException: Unexpected java.util.zip.ZipException ("invalid entry compressed size (expected 1506 but got 1507 bytes)") 
(only duplicate entry execptions are expected!) 
    at io.brainstone.github.installer.FileUtils.makeNewZipFromInputStreamList(FileUtils.java:309) 
    at io.brainstone.github.installer.Main.startInstalling(Main.java:224) 
    at io.brainstone.github.installer.Window$3$1.run(Window.java:183) 
Caused by: java.util.zip.ZipException: invalid entry compressed size (expected 1506 but got 1507 bytes) 
    at java.util.zip.ZipOutputStream.closeEntry(Unknown Source) 
    at java.util.zip.ZipOutputStream.putNextEntry(Unknown Source) 
    at io.brainstone.github.installer.FileUtils.makeNewZipFromInputStreamList(FileUtils.java:300) 
    ... 2 more 

異常是由我自己的代碼引發的。這告訴我發生了意外的異常。預計只有duplicate entry例外。 (這是一招我用我的條目覆蓋含義是在列表的最後歸檔具有最高優先級擁有的文件。)

要明確的事情了,這是我的代碼:

public static void makeNewZipFromInputStreamList(File outputFile, 
      ArrayList<InputStream> inputStreamList, 
      ArrayList<String> includeList, ArrayList<String> excludeList) 
      throws IOException, IllegalArgumentException { 
     final int sizeOfLists[] = new int[] { inputStreamList.size(), 
       includeList.size(), excludeList.size() }; 

     if ((sizeOfLists[0] != sizeOfLists[1]) 
       || (sizeOfLists[0] != sizeOfLists[2]) 
       || (sizeOfLists[1] != sizeOfLists[2])) 
      throw new IllegalArgumentException(
        "The ArrayLists do not have the same size (" 
          + sizeOfLists[0] + ", " + sizeOfLists[1] + ", " 
          + sizeOfLists[2] + ")"); 

     final ZipOutputStream zipOutputFile = new ZipOutputStream(
       new FileOutputStream(outputFile)); 

     final int size = sizeOfLists[0]; 
     final InputStream inputStreamTempArray[] = inputStreamList 
       .toArray(new InputStream[size]); 
     final String includeArray[] = includeList.toArray(new String[size]); 
     final String excludeArray[] = excludeList.toArray(new String[size]); 
     final ZipInputStream inputStreamArray[] = new ZipInputStream[size]; 

     HashMap<String, Object[]> tmp; 

     int i, j; 
     String fileName; 
     ZipEntry entry; 

     for (i = size - 1; i >= 0; i--) { 
      inputStreamArray[i] = new ZipInputStream(inputStreamTempArray[i]); 

      if (includeArray[i] == null) { 
       includeArray[i] = ""; 
      } 

      if (excludeArray[i] == null) { 
       excludeArray[i] = ""; 
      } 

      while ((entry = inputStreamArray[i].getNextEntry()) != null) { 
       fileName = entry.getName(); 

       if (fileName.matches(includeArray[i]) 
         || !fileName.matches(excludeArray[i])) { 
        try { 
         zipOutputFile.putNextEntry(entry); // Here is the inital exception thrown! 

         if (!entry.isDirectory()) { 
          copyStream(inputStreamArray[i], zipOutputFile, 
            false, false); 
         } 
        } catch (ZipException ex) { 
         if (!ex.getMessage() 
           .matches("duplicate entry: .*\\..*")) { 
          throw new RuntimeException(
            "Unexpected " 
              + ex.getClass().getName() 
              + " (\"" 
              + ex.getMessage() 
              + "\")\n(only duplicate entry execptions are expected!)", 
            ex); 
         } 
        } 
       } 
      } 

      inputStreamArray[i].close(); 
     } 

     zipOutputFile.close(); 
    } 
+0

這是發生在某些特定的條目或全部嗎? –

+0

我發生的最公平的。這是一種奇怪的。 (如果我不想在這裏拋出異常,那麼只會爲大多數其他文件執行此操作) – BrainStone

+0

@JimGarrison此解決方案對我無效。這傢伙正在使用JarEntry。我正在使用ZipEntry。當我使用新的ZipEntry(entry.getName())時,我得到了由該行引起的'NullPointerException'! – BrainStone

回答

1

如果您使用的是Java SE 7,請考慮使用NIO.2 File API。

請注意,我已經寫了一些實用的方法來目錄複製到和使用NIO.2文件API Zip文件(該庫是開源的):

Maven的:

<dependency> 
    <groupId>org.softsmithy.lib</groupId> 
    <artifactId>softsmithy-lib-core</artifactId> 
    <version>0.3</version> 
</dependency> 

教程:

http://softsmithy.sourceforge.net/lib/current/docs/tutorial/nio-file/index.html

+0

我沒有將目錄添加到inital zip。我添加其他拉鍊。但是一旦沒有看到快速解決方案,我會查看它,因爲除了這個錯誤之外,其他所有工作都可以正常工作! – BrainStone

+0

我的觀點是,就NIO.2 API而言,壓縮文件的根目錄也是一個目錄。 Zip是另一個FileSystem:http://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystem.html#getRootDirectories%28%29 – Puce