разархивируйте zip-файл в той же иерархии, используя java.util.ZipFile

учитывая zip-файл с несколькими вложенными структурами каталогов, как мне распаковать его в ту же древовидную структуру? предоставляет ли ZipFile.entries() перечисление в любом порядке?


person Community    schedule 18.01.2011    source источник


Ответы (4)


Zip не предлагает структуру каталогов как таковую. Древовидная структура построена с полным путем к каждой записи. ZipFile перечисляет записи так же, как они были добавлены в файл.

Примечание: java.util.ZipEntry.isDirectory() просто проверяет, является ли последний символ имени «/», вот как это работает.

Что вам нужно, чтобы извлечь файлы в тот же каталог. Затем разберите имя так:

for(ZipEntry zipEntry : java.util.Collections.list(zipFile.entries())){//lazislav
    String name = zipEntry.getName();
    int idx = name.lastIndexOf('/');
    if (idx>=0) name=name.substring(idx)
    if (name.length()==0) continue;

    File f = new File(targetDir, name);

}

Это должно сделать это более или менее (вам все еще нужно позаботиться о повторяющихся именах файлов и т. д.)

person bestsss    schedule 18.01.2011

Это мое.

В файле вы указываете файл, который хотите развернуть в целевом каталоге, вы должны указать целевое местоположение как «новый файл («/tmp/foo/bar»)». Если вы хотите извлечь в текущий каталог, вы можете указать targetDir = новый файл ("".")

public static void unzip(File file, File targetDir) throws ZipException,
        IOException {
    targetDir.mkdirs();
    ZipFile zipFile = new ZipFile(file);
    try {
        Enumeration<? extends ZipEntry> entries = zipFile.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            File targetFile = new File(targetDir, entry.getName());
            if (entry.isDirectory()) {
                targetFile.mkdirs();
            } else {
                InputStream input = zipFile.getInputStream(entry);
                try {
                    OutputStream output = new FileOutputStream(targetFile);
                    try {
                        copy(input, output);
                    } finally {
                        output.close();
                    }
                } finally {
                    input.close();
                }
            }
        }
    } finally {
        zipFile.close();
    }
}

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

Работал на меня. Удачи.

person Luigi R. Viggiano    schedule 03.02.2011
comment
отличный код хорошо работал для меня, а также сохранял все папки и структуру внутри zip такими же, как мне было нужно - person GFlam; 04.06.2011
comment
на самом деле после его использования немного не работает с большими файлами, по какой-то причине у меня есть почтовый индекс размером 105 МБ, и он даже не начинает его распаковывать. - person GFlam; 04.06.2011
comment
веселая. вы получаете какие-либо исключения? - person Luigi R. Viggiano; 12.07.2011

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

     public static File unzip(File inFile, File outFolder)
 {  final int BUFFER = 2048;
      try
      {
           BufferedOutputStream out = null;
           ZipInputStream  in = new ZipInputStream(
                                         new BufferedInputStream(
                                              new FileInputStream(inFile)));
           ZipEntry entry;
           while((entry = in.getNextEntry()) != null)
           {
                //System.out.println("Extracting: " + entry);
                int count;
                byte data[] = new byte[BUFFER];

                //We will try to reconstruct the entry directories
                File entrySupposedPath = new File(outFolder.getAbsolutePath()+File.separator+entry.getName());

                //Does the parent folder exist?
                if (!entrySupposedPath.getParentFile().exists()){
                    entrySupposedPath.getParentFile().mkdirs();
                }


                // write the files to the disk
                out = new BufferedOutputStream(
                          new FileOutputStream(outFolder.getPath() + "/" + entry.getName()),BUFFER);

                while ((count = in.read(data,0,BUFFER)) != -1)
                {
                     out.write(data,0,count);
                }
                out.flush();
                out.close();
           }
           in.close();
           return outFolder;
      }
      catch(Exception e)
      {
           e.printStackTrace();
           return inFile;
      }
 }
person Taiko    schedule 15.06.2011
comment
Работает идеально! Сохраняет ту же иерархию - person Manu Janardhanan; 25.06.2016

Зачем вам порядок?

Если запись ZipFile имеет имя /a/b/c/file.txt, вы можете определить имя каталога /a/b/c, а затем создать в дереве каталог с именем a/b/c.

person dogbane    schedule 18.01.2011