2012-10-05 98 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