2010-08-31 3 views
10

Я хотел бы сделать что-то подобное в моей программе:Утилита для распаковки всего архива в каталог в Java

File zipFile = .....; 
File destDir = ....;  
ImaginaryZipUtility.unzipAllTo(zipFile, destdir); 

Я не могу быть первым, чтобы сделать это из программы. Где найти полезный метод, например, выше? Я попытался посмотреть на apache commons-io, но ничего там. Итак, где я должен смотреть?

+0

Я добавил это как запрос функции в Apache commons-compress: https://issues.apache.org/jira/browse/COMPRESS-118 – eirikma

+5

У нас есть сейчас 2011 год, и даже нет (общего) Сторонняя библиотека для извлечения ZIP в Java с помощью одного вызова? WTF – Kutzi

ответ

0

Похоже, что это можно делать то, что я хочу использовать библиотеку TrueZip: https://truezip.dev.java.net/manual-6.html#Copying

Это не идеальная ситуация, так как библиотека довольно большой и с большим объем работы, чем мне нужно (а также с некоторыми своеобразными и запутанными деталями, такими как организация вокруг подклассов java.io.File, которые также называются файлом для использования в классах, которые обычно также обрабатывают экземпляры java.io.File!).

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

Я думаю, что это типичный пример из-за того, что опытные разработчики переходят с Java на Ruby. Несмотря на обилие библиотек в java, слишком многие из них плохо разработаны, поэтому простые операции становятся столь же трудными, как и более специализированные. Похоже, что они написаны снизу вверх технологическими специалистами, которые больше стремятся разоблачить все детали и возможности, а не просто делать повседневные задачи. Люди apache заслуживают похвалы за создание библиотек, которые освобождают ваш класс от строк кода, особенно циклов и условных выражений, которые не связаны с бизнес-целями класса.

+0

hmm. не работает точно так, как я ожидал. он переписывается в файлы jar внутри zip и извлекает их тоже, несмотря на меня, используя код, который, как сказано в руководстве, не сделает этого. Не то, что я имел в виду. – eirikma

+0

Попробуйте TrueZIP 7. Класс теперь называется TFile, и его API является чистым и продуктивным. Если вам нравится подход Ruby, вам тоже может понравиться. –

1

Ну, java.util.zip есть классы, чтобы сделать то, что вы хотите в очень straighforward образом

+0

Я знаю, но это не то, что я имел в виду. См. Комментарий на ответ jsshah ниже. – eirikma

+1

Я не мог найти там однострочных лайнеров. Я что-то упустил, @helios? –

+0

№ Нет ни одного лайнера, просто инструменты для реализации в очень уединенном виде, что нужно. Прочтите zip-файл (его записи), для каждой записи сделайте dir, откройте файл, выгрузите содержимое в него и закройте. Только то, что предлагает jsshah, но, возможно, немного более компактный (и используя Commons-fileupload's 'Streams.copy'). – helios

7

очень старый код, который я смог выкопать

package com.den.frontend; 

импорт java.util. ; импорт java.util.zip.; импорт java.io. *;

public class ZIPUtility 
{ 
    public static final int BUFFER_SIZE = 2048; 

    //This function converts the zip file into uncompressed files which are placed in the 
    //destination directory 
    //destination directory should be created first 
    public static boolean unzipFiles(String srcDirectory, String srcFile, String destDirectory) 
    { 
     try 
     { 
      //first make sure that all the arguments are valid and not null 
      if(srcDirectory == null) 
      { 
       System.out.println(1); 
       return false; 
      } 
      if(srcFile == null) 
      { 
       System.out.println(2); 
       return false; 
      } 
      if(destDirectory == null) 
      { 
       System.out.println(3); 
       return false; 
      } 
      if(srcDirectory.equals("")) 
      { 
       System.out.println(4); 
       return false; 
      } 
      if(srcFile.equals("")) 
      { 
       System.out.println(5); 
       return false; 
      } 
      if(destDirectory.equals("")) 
      { 
       System.out.println(6); 
       return false; 
      } 
      //now make sure that these directories exist 
      File sourceDirectory = new File(srcDirectory); 
      File sourceFile = new File(srcDirectory + File.separator + srcFile); 
      File destinationDirectory = new File(destDirectory); 

      if(!sourceDirectory.exists()) 
      { 
       System.out.println(7); 
       return false; 
      } 
      if(!sourceFile.exists()) 
      { 
       System.out.println(sourceFile); 
       return false; 
      } 
      if(!destinationDirectory.exists()) 
      { 
       System.out.println(9); 
       return false; 
      } 

      //now start with unzip process 
      BufferedOutputStream dest = null; 

      FileInputStream fis = new FileInputStream(sourceFile); 
      ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis)); 

      ZipEntry entry = null; 

      while((entry = zis.getNextEntry()) != null) 
      { 
       String outputFilename = destDirectory + File.separator + entry.getName(); 

       System.out.println("Extracting file: " + entry.getName()); 

       createDirIfNeeded(destDirectory, entry); 

       int count; 

       byte data[] = new byte[BUFFER_SIZE]; 

       //write the file to the disk 
       FileOutputStream fos = new FileOutputStream(outputFilename); 
       dest = new BufferedOutputStream(fos, BUFFER_SIZE); 

       while((count = zis.read(data, 0, BUFFER_SIZE)) != -1) 
       { 
        dest.write(data, 0, count); 
       } 

       //close the output streams 
       dest.flush(); 
       dest.close(); 
      } 

      //we are done with all the files 
      //close the zip file 
      zis.close(); 

     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
      return false; 
     } 

     return true; 
    } 

    private static void createDirIfNeeded(String destDirectory, ZipEntry entry) 
    { 
     String name = entry.getName(); 

     if(name.contains("/")) 
     { 
      System.out.println("directory will need to be created"); 

      int index = name.lastIndexOf("/"); 
      String dirSequence = name.substring(0, index); 

      File newDirs = new File(destDirectory + File.separator + dirSequence); 

      //create the directory 
      newDirs.mkdirs(); 
     } 
    } 

} 
+2

спасибо, оба вы, но это не то, что я имел в виду. Я знаю, что можно перемещать записи zip, создавать необходимые каталоги и так далее, используя std api. Я не хочу все это в своей программе. Это слишком много кода: он уродлив и запутан. Для всех программ, которые хотят разархивировать файлы, не обязательно, чтобы включать все эти вещи. Я хочу, чтобы однострочная команда распаковывала архив, как и в командной строке. Трудно поверить, что класс ZipFile не имеет метода unzipTo (directory). Вместо этого для этого требуется 50 строк. Что это за дизайн API? – eirikma

+1

hmm. Может быть, я должен попробовать это: Runtime.getRuntime() Exec (новый String [] { "распаковать", zipfile.getAbsolutePath(), "-d", destdir.getAbsolutePath(), });. – eirikma

+0

Преимущество использования JavaClass - переносимость (вам не нужно беспокоиться о собственных двоичных файлах) – helios

6

Я знаю, что я очень допоздна к шоу, но я искал то же самое и нашел это через google. Самый простой способ, который я нашел, - это муравьиная задача «распаковать». Вы можете использовать его без какой-либо сложных муравьев установки (есть такие вещи, как ProjectHelper построить полный муравей проект) из источника Java, включив в

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

Код для распаковки файла в каталоге выглядит следующим образом

org.apache.ant.compress.taskdefs.Unzip u = new Unzip(); 
u.setSrc(new File("<archive.zip>")); 
u.setDest(new File("<targetDir>")); 
u.execute(); 
Смежные вопросы