2012-10-05 95 views
2

我試圖解壓縮一個壓縮文件(該文件包含許多子文件夾和文件)。Uzip文件夾遞歸-android

I am not able to create sub-folders while unzipping the file. 

每次我收到一個錯誤說:

No such file or directory. 

我已經搜索了很多關於此類似:

  1. Android - Unzip a folder?
  2. http://www.roseindia.net/tutorial/java/corejava/zip/ZipIsDirectory.html
  3. Unzip a zipped file on sd card in Android application
  4. How to unzip files recursively in Java?

但是,沒有什麼幫助我。

下面是我曾嘗試:

public class UnZipper { 

    private static final String TAG = "UnZip"; 
    private String mFileName, mDestinationPath; 

    public UnZipper(String fileName, String destinationPath) { 
     mFileName = fileName; 
     mDestinationPath = destinationPath; 
    } 

    public String getFileName() { 
     return mFileName; 
    } 

    public String getDestinationPath() { 
     return mDestinationPath; 
    } 

    // shrikant 
    public void unzip() { 
     String fullPath = mFileName; 
     Log.d(TAG, "unzipping " + mFileName + " to " + mDestinationPath); 
     doInBackground(fullPath, mDestinationPath); 
    } 

    // shrikant: I have changed return type from Boolean to boolean. 
    protected boolean doInBackground(String filePath, String destinationPath) { 

     File archive = new File(filePath); 
     boolean returnValue = false; 
     try { 
      ZipFile zipfile = new ZipFile(archive); 

      for (Enumeration e = zipfile.entries(); e.hasMoreElements();) { 

       ZipEntry entry = (ZipEntry) e.nextElement(); 
       try { 
        unzipEntry(zipfile, entry, destinationPath); 
        Log.d("Unzipped", entry.getName()); 
        returnValue = true; 
       } catch (Exception ex) { 
        Log.e(TAG, 
          "Error while extracting file: " + entry 
            + ex.getMessage()); 
       } 
      } 
     } catch (Exception e) { 
      Log.e(TAG, "Error while extracting file " + archive, e); 
      // return false; 
     } 
     return returnValue; 
    } 

    // shrikant: I have changed return type from void to boolean. 
    /** 
    * Unzips the zipped file into outputDir path. 
    * 
    * @param zipfile 
    * @param entry 
    * @param outputDir 
    * @throws IOException 
    */ 
    private void unzipEntry(ZipFile zipfile, ZipEntry entry, String outputDir) 
      throws IOException { 
     Log.d("CURRENT ZIP", entry.getName()); 
     String _dir = null, fileName = null; 
     if (entry.getName().contains("\\")) { 

      _dir = entry.getName().substring(0, entry.getName().indexOf('\\')); 
      createDir(new File(outputDir, _dir)); 
      fileName = entry.getName().substring(entry.getName().indexOf('\\')); 
     } 

     // Change by Prashant : To Remove "/" from file Name Date : 5/01/2011 
     if (fileName.toString().startsWith("\\")) { 
      fileName = fileName.substring(1); // End 
     } 

     if (_dir != "") 
      outputDir = outputDir + "/" + _dir; 

     File outputFile = new File(outputDir, fileName); 
     if (!outputFile.getParentFile().exists()) { 
      createDir(outputFile.getParentFile()); 
     } 
     Log.d("OUTPUT FILE", outputDir + fileName); 
     Log.v(TAG, "Extracting: " + entry); 

     Log.d("FOUND inside unzipEntry()", entry.getName()); 

     BufferedInputStream inputStream = new BufferedInputStream(
       zipfile.getInputStream(entry)); 

// **here I am getting error.** 

     BufferedOutputStream outputStream = new BufferedOutputStream(
       new FileOutputStream(outputFile)); 

// **above line.** 

     try { 
      copy(inputStream, outputStream); 
     } finally { 
      outputStream.close(); 
      inputStream.close(); 
     } 

    } 

    private void createDir(File dir) { 
     if (dir.exists()) { 
      return; 
     } 
     Log.v(TAG, "Creating dir " + dir.getName()); 
     if (!dir.mkdirs()) { 
      throw new RuntimeException("Cannot create dir " + dir); 
     } 
    } 

    private void copy(BufferedInputStream input, BufferedOutputStream output) 
      throws IOException { 
     byte[] buffer = new byte[4096]; 
     int size; 
     while ((size = input.read(buffer)) != -1) 
      output.write(buffer, 0, size); 
    } 

} 

我的問題是:(請看代碼)

當我打電話unzipEntry(),當它遇到的子文件夾,它通過類似「/data/abc.ext」的東西,但我的文件系統不包含名爲「數據」的任何文件夾,我甚至試圖創建它,但未能這樣做。

那麼如何創建從壓縮文件到目標路徑的子文件夾?

我甚至試過的方法:

if(entry.isDirectory) { 
// create directory 
} 

但是,這不會被調用,因爲unzipEntry()(請看在for() loop)直接通過下子文件夾中的文件。

請幫我解決這個問題。

謝謝。

+0

您是否有權限在清單中寫入SDcard集? –

+0

mDestinationPath的價值是什麼? – njzk2

+0

mDestinationPath包含將保存解壓縮文件的文件路徑。 – Shrikant

回答

6

哦是的!我已經解決了它.. :)

我寫了下面的函數,如果需要將遞歸地創建子文件夾。

這是經過試用和測試的功能,將成功解壓任何文件。

/** 
    * Unzips the file (recursively creates sub-folder if exists.) 
    * 
    * @param tempFileName 
    *   The zip file. 
    * @param destinationPath 
    *   The destination path where unzipped file will be saved. 
    */ 
    public void unzipFile(String tempFileName, String destinationPath) { 
     try { 

      int index = destinationPath.lastIndexOf("\\"); 
      String fileString = destinationPath.substring(index); 

      File extFile = new File("/mnt/sdcard/courses1", fileString); 
      if(!extFile.exists()) { 
       createDir(extFile); 
      } 

      byte[] buffer = new byte[1024]; 

      FileInputStream fin = new FileInputStream(tempFileName); 
      ZipInputStream zin = new ZipInputStream(fin); 
      ZipEntry zipentry = null; 
      if (!(zin.available() == 0)) { 
       byte[] startBuffer = new byte[8]; 

       while ((zipentry = zin.getNextEntry()) != null) { 
        String zipName = zipentry.getName(); 
        if (zipName.startsWith("/")) { 
         zipName = zipentry.getName(); 
        } else if (zipName.startsWith("\\")) { 
         zipName = zipentry.getName(); 
        } else { 
         zipName = "/" + zipentry.getName(); 
        } 

        String fileName = destinationPath + zipName; 
        fileName = fileName.replace("\\", "/"); 
        fileName = fileName.replace("//", "/"); 

        if (zipentry.isDirectory()) { 
         createDir(new File(fileName)); 
         continue; 
        } 

        String name = zipentry.getName(); 
        int start, end = 0; 
        while (true) { 

         start = name.indexOf('\\', end); 
         end = name.indexOf('\\', start + 1); 
         if (start > 0) 
          "check".toString(); 
         if (end > start && end > -1 && start > -1) { 
          String dir = name.substring(1, end); 

          createDir(new File(destinationPath + '/' + dir)); 
          // name = name.substring(end); 
         } else 
          break; 
        } 

        File file = new File(fileName); 

        FileOutputStream tempDexOut = new FileOutputStream(file); 
        int BytesRead = 0; 

        if (zipentry != null) { 
         if (zin != null) { 
          while ((BytesRead = zin.read(buffer)) != -1) { 
           tempDexOut.write(buffer, 0, BytesRead); 
          } 
          tempDexOut.close(); 
         } 
        } 
       } 
      } 

     } catch (Exception e) { 
      Log.e("Exception", e.getMessage()); 
     } 
    } 

我希望它可以幫助別人。 :)

謝謝。

+0

你能分享完整的代碼嗎? – Jomia