2011-07-13 74 views
12

我需要壓縮一個「項目」文件夾,以允許用戶通過電子郵件共享項目。我發現一個類將多個文件壓縮成一個壓縮文件,但我需要在我的壓縮文件中保留文件夾結構。有沒有什麼辦法在Android上實現這一點?提前致謝。zip /壓縮文件夾中的所有文件安卓

+0

澄清,你的意思是Android開發項目或在應用程序中開發的項目? –

+0

在應用程序中開發的項目,對此感到抱歉。此外,我認爲這是我需要的:http://stackoverflow.com/questions/1399126/java-util-zip-recreating-directory-structure但是當我複製它,我盡我所能,但無法找出如何到該行:Deque queue = new LinkedList ();上班。我知道Deque是一個接口,LinkedList實現它,但eclipes只是給我錯誤。 – Mark

+1

沒關係,經過大量搜索後發現如何做到這一點:http://www.crazysquirrel.com/computing/java/basics/java-directory-zipping.jspx – Mark

回答

1

如果使用java.util.zip對象,則可以編寫不修改目錄結構的腳本。

34

此代碼應該做的伎倆。

注意:您必須向您的應用程序添加文件寫入權限,方法是向manifest.xml文件添加WRITE_EXTERNAL_STORAGE權限。

/* 
* 
* Zips a file at a location and places the resulting zip file at the toLocation 
* Example: zipFileAtPath("downloads/myfolder", "downloads/myFolder.zip"); 
*/ 

public boolean zipFileAtPath(String sourcePath, String toLocation) { 
    final int BUFFER = 2048; 

    File sourceFile = new File(sourcePath); 
    try { 
     BufferedInputStream origin = null; 
     FileOutputStream dest = new FileOutputStream(toLocation); 
     ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
       dest)); 
     if (sourceFile.isDirectory()) { 
      zipSubFolder(out, sourceFile, sourceFile.getParent().length()); 
     } else { 
      byte data[] = new byte[BUFFER]; 
      FileInputStream fi = new FileInputStream(sourcePath); 
      origin = new BufferedInputStream(fi, BUFFER); 
      ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath)); 
      out.putNextEntry(entry); 
      int count; 
      while ((count = origin.read(data, 0, BUFFER)) != -1) { 
       out.write(data, 0, count); 
      } 
     } 
     out.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return false; 
    } 
    return true; 
} 

/* 
* 
* Zips a subfolder 
* 
*/ 

private void zipSubFolder(ZipOutputStream out, File folder, 
     int basePathLength) throws IOException { 

    final int BUFFER = 2048; 

    File[] fileList = folder.listFiles(); 
    BufferedInputStream origin = null; 
    for (File file : fileList) { 
     if (file.isDirectory()) { 
      zipSubFolder(out, file, basePathLength); 
     } else { 
      byte data[] = new byte[BUFFER]; 
      String unmodifiedFilePath = file.getPath(); 
      String relativePath = unmodifiedFilePath 
        .substring(basePathLength); 
      FileInputStream fi = new FileInputStream(unmodifiedFilePath); 
      origin = new BufferedInputStream(fi, BUFFER); 
      ZipEntry entry = new ZipEntry(relativePath); 
      out.putNextEntry(entry); 
      int count; 
      while ((count = origin.read(data, 0, BUFFER)) != -1) { 
       out.write(data, 0, count); 
      } 
      origin.close(); 
     } 
    } 
} 

/* 
* gets the last path component 
* 
* Example: getLastPathComponent("downloads/example/fileToZip"); 
* Result: "fileToZip" 
*/ 
public String getLastPathComponent(String filePath) { 
    String[] segments = filePath.split("/"); 
    if (segments.length == 0) 
     return ""; 
    String lastPathComponent = segments[segments.length - 1]; 
    return lastPathComponent; 
} 
+0

嘿@HailZeon!偉大的代碼,真的很有幫助。 getLastPathComponent(sourcePath)做了什麼以及它是如何定義的?謝謝! –

+0

嘿@RaymondMachira。我添加了getLastPathComponent的定義。它基本上需要一個路徑(「folder1/subfolder/example.txt」)並返回「folder1/subfolder /」。該zip文件可能沒有在其中定義的包含文件夾,所以我們需要去除子路徑並添加它。 – HailZeon

+0

static final int BUFFER = 2048; – user1546570

12

這是我要做的事:

private static void zipFolder(String inputFolderPath, String outZipPath) { 
    try { 
     FileOutputStream fos = new FileOutputStream(outZipPath); 
     ZipOutputStream zos = new ZipOutputStream(fos); 
     File srcFile = new File(inputFolderPath); 
     File[] files = srcFile.listFiles(); 
     Log.d("", "Zip directory: " + srcFile.getName()); 
     for (int i = 0; i < files.length; i++) { 
      Log.d("", "Adding file: " + files[i].getName()); 
      byte[] buffer = new byte[1024]; 
      FileInputStream fis = new FileInputStream(files[i]); 
      zos.putNextEntry(new ZipEntry(files[i].getName())); 
      int length; 
      while ((length = fis.read(buffer)) > 0) { 
       zos.write(buffer, 0, length); 
      } 
      zos.closeEntry(); 
      fis.close(); 
     } 
     zos.close(); 
    } catch (IOException ioe) { 
     Log.e("", ioe.getMessage()); 
    } 
} 
+1

完美答案!簡單和偉大的 – Khay

+0

如果源文件夾包含另一個文件夾不能正常工作 – tibbi

0
public static boolean zip(File sourceFile, File zipFile) { 
    List<File> fileList = getSubFiles(sourceFile, true); 
    ZipOutputStream zipOutputStream = null; 
    try { 
     zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFile)); 
     int bufferSize = 1024; 
     byte[] buf = new byte[bufferSize]; 
     ZipEntry zipEntry; 
     for(int i = 0; i < fileList.size(); i++) { 
      File file = fileList.get(i); 
      zipEntry = new ZipEntry(sourceFile.toURI().relativize(file.toURI()).getPath()); 
      zipOutputStream.putNextEntry(zipEntry); 
      if (!file.isDirectory()) { 
       InputStream inputStream = new BufferedInputStream(new FileInputStream(file)); 
       int readLength; 
       while ((readLength = inputStream.read(buf, 0, bufferSize)) != -1) { 
        zipOutputStream.write(buf, 0, readLength); 
       } 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return false; 
    } finally { 
     IoUtils.closeOS(zipOutputStream); 
    } 
    return true; 
}  

public static List<File> getSubFiles(File baseDir, boolean isContainFolder) { 
    List<File> fileList = new ArrayList<>(); 
    File[] tmpList = baseDir.listFiles(); 
    for (File file : tmpList) { 
     if (file.isFile()) { 
      fileList.add(file); 
     } 
     if (file.isDirectory()) { 
      if (isContainFolder) { 
       fileList.add(file); //key code 
      } 
      fileList.addAll(getSubFiles(file)); 
     } 
    } 
    return fileList; 
} 
0

使用此location的zip4j庫。將jar文件導入到您的"app/libs/"文件夾中。並使用下面的代碼來壓縮你的目錄/文件...

try { 
    File input = new File("path/to/your/input/fileOrFolder"); 
    String destinationPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "zippedItem.zip"; 
    ZipParameters parameters = new ZipParameters(); 
    parameters.setCompressionMethod(Zip4jConstants.COMP_STORE); 
    parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); 
    File output = new File(destinationPath); 
    ZipFile zipFile = new ZipFile(output); 
    // .addFolder or .addFile depending on your input 
    if (sourceFile.isDirectory()) 
     zipFile.addFolder(input, parameters); 
    else 
     zipFile.addFile(input, parameters); 
    // Your input file/directory has been zipped at this point and you 
    // can access it as a normal file using the following line of code 
    File zippedFile = zipFile.getFile(); 
} catch (ZipException e) { 
    Log.e(TAG, Log.getStackTraceString(e)); 
}