2012-05-17 4 views
16

Есть ли какой-нибудь пример кода, как particaly распаковать папку из ZIP в мой желаемый каталог? Я прочитал все файлы из папки «FOLDER» в массив байтов, как мне воссоздать из его файловой структуры?Java ZIP - как распаковать папку?

ответ

0

Вы должны получить все записи из архива:

Enumeration entries = zipFile.getEntries(); 

затем itareting над этим перечислением получить ZipEntry от него, проверить, является ли он каталогом или нет, а также создавать dirctrory или просто извлечь файл respectivly ,

+0

Это часть мне на самом деле нужно ... У меня есть доступ к моей папке в ZIP и хотите сохранить его в sdcard/foldername с его содержимым из ZIP. Как это сделать? – Waypoint

+1

ну, я думаю, вам стоит попытаться написать какой-то код, взглянуть на некоторые примеры, и если вы потерпите неудачу или застрянете - вернитесь сюда с вашим кодом. –

21

Вот код, который я использую. Измените BUFFER_SIZE для ваших нужд.

import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipInputStream; 

public class ZipUtils 
{ 
    private static final int BUFFER_SIZE = 4096; 

    private static void extractFile(ZipInputStream in, File outdir, String name) throws IOException 
    { 
    byte[] buffer = new byte[BUFFER_SIZE]; 
    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(outdir,name))); 
    int count = -1; 
    while ((count = in.read(buffer)) != -1) 
     out.write(buffer, 0, count); 
    out.close(); 
    } 

    private static void mkdirs(File outdir,String path) 
    { 
    File d = new File(outdir, path); 
    if(!d.exists()) 
     d.mkdirs(); 
    } 

    private static String dirpart(String name) 
    { 
    int s = name.lastIndexOf(File.separatorChar); 
    return s == -1 ? null : name.substring(0, s); 
    } 

    /*** 
    * Extract zipfile to outdir with complete directory structure 
    * @param zipfile Input .zip file 
    * @param outdir Output directory 
    */ 
    public static void extract(File zipfile, File outdir) 
    { 
    try 
    { 
     ZipInputStream zin = new ZipInputStream(new FileInputStream(zipfile)); 
     ZipEntry entry; 
     String name, dir; 
     while ((entry = zin.getNextEntry()) != null) 
     { 
     name = entry.getName(); 
     if(entry.isDirectory()) 
     { 
      mkdirs(outdir,name); 
      continue; 
     } 
     /* this part is necessary because file entry can come before 
     * directory entry where is file located 
     * i.e.: 
     * /foo/foo.txt 
     * /foo/ 
     */ 
     dir = dirpart(name); 
     if(dir != null) 
      mkdirs(outdir,dir); 

     extractFile(zin, outdir, name); 
     } 
     zin.close(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
    } 
} 
+4

Вы не должны проглатывать IOException. –

+0

Это работает для меня. Благодарю. –

10

То же можно достичь с помощью библиотеки Ant Compress. Он сохранит структуру папок.

Maven зависимость: -

<dependency> 
    <groupId>org.apache.ant</groupId> 
    <artifactId>ant-compress</artifactId> 
    <version>1.2</version> 
</dependency> 

Пример кода: -

Unzip unzipper = new Unzip(); 
unzipper.setSrc(theZIPFile); 
unzipper.setDest(theTargetFolder); 
unzipper.execute(); 
24

Я не уверен, что вы имеете в виду particaly? Вы имеете в виду сделать это самостоятельно без помощи API?

В случае, если вы не возражаете, используя некоторые библиотеки с открытым исходным кодом, есть прохладное API для этого там называется zip4J

Он прост в использовании, и я думаю, что есть хорошие отзывы о нем. Смотрите этот пример:

String source = "folder/source.zip"; 
String destination = "folder/source/"; 

try { 
    ZipFile zipFile = new ZipFile(source); 
    zipFile.extractAll(destination); 
} catch (ZipException e) { 
    e.printStackTrace(); 
} 

Если файлы, которые вы хотите разархивировать иметь пароли, вы можете попробовать это:

String source = "folder/source.zip"; 
String destination = "folder/source/"; 
String password = "password"; 

try { 
    ZipFile zipFile = new ZipFile(source); 
    if (zipFile.isEncrypted()) { 
     zipFile.setPassword(password); 
    } 
    zipFile.extractAll(destination); 
} catch (ZipException e) { 
    e.printStackTrace(); 
} 

Я надеюсь, что это полезно.

2

Это простое решение, которое следует за более современными соглашениями. Вы можете изменить размер буфера, чтобы быть меньше, если вы разархивируете большие файлы. Это значит, что вы не храните всю информацию о файлах в памяти.

public static void unzip(File source, String out) throws IOException { 
    try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source))) { 

     ZipEntry entry = zis.getNextEntry(); 

     while (entry != null) { 

      File file = new File(out, entry.getName()); 

      if (entry.isDirectory()) { 
       file.mkdirs(); 
      } else { 
       File parent = file.getParentFile(); 

       if (!parent.exists()) { 
        parent.mkdirs(); 
       } 

       try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) { 

        byte[] buffer = new byte[Math.toIntExact(entry.getSize())]; 

        int location; 

        while ((location = zis.read(buffer)) != -1) { 
         bos.write(buffer, 0, location); 
        } 
       } 
      } 
      entry = zis.getNextEntry(); 
     } 
    } 
} 
0

Здесь более «современный» полный код, основанный на this пост, но переработан (и используя Lombok):

import lombok.experimental.var; 
import lombok.val; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.util.zip.ZipInputStream; 

import static java.nio.file.Files.createDirectories; 

public class UnZip 
{ 
    public static void unZip(String sourceZipFile, String outputDirectory) throws IOException 
    { 
     val folder = new File(outputDirectory); 
     createDirectories(folder.toPath()); 

     try (val zipInputStream = new ZipInputStream(new FileInputStream(sourceZipFile))) 
     { 
      var nextEntry = zipInputStream.getNextEntry(); 

      while (nextEntry != null) 
      { 
       val fileName = nextEntry.getName(); 
       val newFile = new File(outputDirectory + File.separator + fileName); 

       createDirectories(newFile.getParentFile().toPath()); 
       writeFile(zipInputStream, newFile); 

       nextEntry = zipInputStream.getNextEntry(); 
      } 

      zipInputStream.closeEntry(); 
     } 
    } 

    private static void writeFile(ZipInputStream inputStream, File file) throws IOException 
    { 
     val buffer = new byte[1024]; 
     try (val fileOutputStream = new FileOutputStream(file)) 
     { 
      int length; 
      while ((length = inputStream.read(buffer)) > 0) 
      { 
       fileOutputStream.write(buffer, 0, length); 
      } 
     } 
    } 
} 
Смежные вопросы