2013-08-06 7 views
2

여러 zip 아카이브를 한 단계로 서로 융합시키는 방법을 만들려고합니다. 코드가 매우 잘 보이며 작동해야합니다. 하지만 실행하면 정말 이상한 예외가 발생합니다 :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 

예외는 내 자신의 코드에 의해 throw됩니다. 이것은 예기치 않은 예외가 발생했음을 나타냅니다. 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

나는 대부분의 enrties에 대해 발생합니다. 어떤 종류의 이상합니다. (예외를 여기에 던지지 않으면 대부분의 다른 파일에서도 예외가 발생합니다.) – BrainStone

+0

@JimGarrison이 솔루션은 저에게 적합하지 않습니다. 이 남자가 JarEntry를 사용하고 있습니다. ZipEntry를 사용하고 있습니다. 'new ZipEntry (entry.getName()) '을 사용하면 해당 줄로 인해'NullPointerException'이 발생합니다! – BrainStone

답변

1

: 물건을 지우려면

이 내 코드입니다. (이 파일을 소유 우선 순위가 가장 높은 목록의 마지막 아카이브를 의미 내 항목 오버라이드에 사용하는 트릭입니다) Java SE 7을 사용하는 경우 NIO.2 File API를 사용하는 것이 좋습니다.

메이븐 :

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

I가와 NIO.2 파일 API를 사용하여 Zip 파일에서 디렉토리를 복사하는 몇 가지 유틸리티 메소드를 작성했습니다

참고 (라이브러리는 오픈 소스입니다) 자습서 :

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

+0

나는 지형 지퍼에 디렉토리를 추가하지 않을 것이다. 다른 지퍼를 추가합니다. 하지만 그 오류 이외에 다른 모든 것들이 작동하기 때문에 빠른 솔루션이 보이지 않는다면 한번 살펴 보겠습니다! – BrainStone

+0

요점은 NIO.2 API의 관점에서 보면 zip 파일의 루트는 디렉토리이기도합니다. Zip은 또 다른 FileSystem입니다. http://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystem.html#getRootDirectories%28%29 – Puce