2014-01-20 22 views
0

我的zip文件,我有幾個zip文件,每個包含多個文件太多,我想使用ZipInputStream類提取。其中有一些圖像。當我嘗試使用BufferedOutputStream提取這些圖像時,它們會部分解壓縮,並且圖像不完整。我不能完全提取使用ZipInputStream

private void extractArchives() { 

    ZipInputStream zis; 

    File archiveDir = new File(
      Environment.getExternalStorageDirectory().getAbsolutePath() + 
    "/archives/"); 

    File[] files = archiveDir.listFiles(); 

    for (int i = 0; i < files.length; ++i) 
    { 
     File file = files[i]; 

     try 
     { 
      zis = new ZipInputStream(new FileInputStream(file)); 
      ZipEntry ze; 

      while ((ze = zis.getNextEntry()) != null) 
      { 
       BufferedOutputStream bos; 
       byte[] buffer = new byte[102400]; 
       int count; 

       while ((count = zis.read(buffer)) != -1) 
       { 
        String fileName = ze.getName(); 

        if (fileName.endsWith(".jpg")) 
        { 
         path += File.separator + fileName; 
         bos = new BufferedOutputStream(new FileOutputStream(path)); 
         bos.write(buffer, 0, count); 
         bos.close(); 
        } 
       } 
      } 

      zis.close(); 

     } 

     catch(FileNotFoundException e) { continue; } 

     //If the file is not a zip file or is a directory 
     catch (IOException e) { continue; } 

    } 
} 

上面的代碼有什麼問題嗎?使用BufferedOutputStream會導致這個問題嗎?我很欣賞任何想法。謝謝。

+0

哪裏變量'files','path'和'zis'申報?你在你的來源除了你的解壓縮問題有一個明確的問題:你總是附加到您的路徑('路徑+ =文件分割符+ fileName')這樣的路徑名變得越來越長,但你沒有創建任何新的目錄。 –

+0

是的,你說得對。我應該改正這一點。不過,我嘗試了一個zip文件和一個圖像,但圖像仍未完全提取。 –

回答

0

着眼於循環,在壓縮項迭代,問題是,你是在從ZIP條目最多102400個字節讀,然後編寫一個新的文件中。如果將相同的映像文件寫入新文件,則下一個最大102400字節。如果路徑名稱與舊文件相同,則會覆蓋舊文件。但是由於你不斷追加到局部變量「路徑」,我不確定數據在哪裏結束。

拉FileOutputStream中的開出內部循環,並保持寫入相同的OutputStream,直到你可以從當前ZipEntry的閱讀沒有更多的字節。然後才能轉到下一個ZipEntry和下一個OutputStream。

這是一個標準的模式來讀取和Java的流之間複製,所以我可以修復你的代碼,而無需的filespathzis的定義,但它會幫助,如果你能發佈一個實際的編譯代碼示例,這樣其他人們也可以從中受益。

生產代碼中需要的另一個改進是將bos.close()包裝在try/finally塊中,以便在從輸入讀取時出現異常時輸出文件也會關閉。

 while ((ze = zis.getNextEntry()) != null) { 
      String fileName = ze.getName(); 

      if (fileName.endsWith(".jpg")) { 
       String filepath = path + File.separator + fileName; 
       BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filepath)); 
       byte[] buffer = new byte[102400]; 
       int count; 
       while ((count = zis.read(buffer)) != -1) { 
        bos.write(buffer, 0, count); 
       } 
       bos.close(); 
      } 
     } 
1

我根據什麼說歐文修改的方法,現在,它的工作原理:

private void extractArchives() { 

    File archiveDir = new File(
       Environment.getExternalStorageDirectory().getAbsolutePath() + 
       "/archives/"); 

    String archivePath = archiveDir.getAbsolutePath(); 

    File[] files = archiveDir.listFiles(); 

    for (int i = 0; i < files.length; ++i) 
    { 
     File file = files[i]; 

     if(!file.isDirectory()) 
     { 
      try { 

       ZipInputStream zis = new ZipInputStream(new FileInputStream(file)); 
       ZipEntry entry = zis.getNextEntry(); 

       while (entry != null) 
       { 
        if(entry.getName().endsWith(".jpg")) 
        { 
         String imagePath = themePath + File.separator + entry.getName(); 

         BufferedOutputStream bos = new BufferedOutputStream(
            new FileOutputStream(imagePath)); 

         byte[] buffer = new byte[4096]; 

         int read = 0; 

         while ((read = zis.read(buffer)) != -1) bos.write(buffer, 0, read); 

         imagePath = ""; 

         bos.close(); 
        } 

        zis.closeEntry(); 

        entry = zis.getNextEntry(); 
       } 

       zis.close(); 
      } 

      catch (FileNotFoundException e) {} 

      catch (IOException e) {} 
     } 
    } 
} 
+0

如果你認爲它是正確的,你能接受我的答案嗎? –

+0

你呢?我在回答中提到你。太慷慨接受! :)) –