2011-07-13 17 views
12

Kullanıcıların projeleri e-posta yoluyla paylaşmalarına izin vermek için bir "proje" klasörü zip gerekiyor. Birden fazla dosyayı tek bir zip halinde sıkıştırmak için bir sınıf buldum, ancak klasör yapısını fermuarım içinde tutmam gerekiyor. Bunu android üzerinde gerçekleştirmenin herhangi bir yolu var mı? Şimdiden teşekkürler.zip/android bir dosya dolu dosyaları sıkıştırmak

+0

Netleştirmek için, Android geliştirme projesi mi yoksa uygulamada geliştirilen bir proje mi demek istiyorsunuz? App geliştirilen –

+0

Proje, bu konuda üzgünüm. Ayrıca bence ihtiyacım olan şey şu: http://stackoverflow.com/questions/1399126/java-util-zip-recreating-directory-structure ama kopyaladığım zaman elimden gelenin en iyisini denedim ama ne olduğunu anlayamadım. çizgiye: Deque sıra = new LinkedList (); çalışmak. Deque'in bir arabirim olduğunu ve LinkedList'in onu uyguladığını biliyorum, ancak eclipes sadece bana hata veriyor. – Mark

+1

Nevermind, bir çok aramadan sonra nasıl yapılacağını öğrendi: http://www.crazysquirrel.com/computing/java/basics/java-directory-zipping.jspx – Mark

cevap

1

Bir java.util.zip nesnesi kullanırsanız, dizin yapısını değiştirmeyen bir komut dosyası yazabilirsiniz.

34

Bu kod hile yapmalıdır.

Not: manifest.xml dosyanıza WRITE_EXTERNAL_STORAGE izni ekleyerek uygulamanıza dosya yazma izinleri eklemeniz gerekir.

/* 
* 
* 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

Hey @HailZeon! Büyük kod ve gerçekten yararlı. GetLastPathComponent (sourcePath) ne yapar ve nasıl tanımlanır? Teşekkürler! –

+0

Hey @RaymondMachira. GetLastPathComponent tanımını ekledim. Temelde bir yol alır ("folder1/subfolder/example.txt") ve "folder1/subfolder /" değerini döndürür. Zip dosyasında, içinde tanımlanmış bir klasör bulunmayabilir, bu yüzden alt yolu dışarı çıkarmalı ve eklemeliyiz. – HailZeon

+0

statik son int BUFFER = 2048; – user1546570

12

bu ben böyle yaparız:

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

mükemmel cevap!basit ve harika çalışıyor – Khay

+0

kaynak klasörü başka bir klasör içeriyorsa düzgün çalışmıyor – 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

bunu kullanın location gelen zip4j kütüphanesi. Kavanoz dosyasını "app/libs/" klasörünüze alın. Dizinlerinizi/dosyalarınızı sıkıştırmak için aşağıdaki kodu kullanın ...

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)); 
}