2010-08-31 11 views
10

bir dizine bütün bir arşivi açın:Utility benim programda böyle bir şey yapmak istiyorum java

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

Ben muhtemelen bir programdan bunu yapmak ilk olamaz. Yukarıdaki gibi bir yardımcı program nerede bulabilirim? Apache commons-io'ya bakmaya çalıştım ama hiçbir şey yok. Peki, nereye bakmalıyım?

+0

Bunu bir özellik isteği olarak ekledim Apache commons-compress: https://issues.apache.org/jira/browse/COMPRESS-118 – eirikma

+5

Şimdi 2011 var ve hatta bir (ortak) yok Java'da tek bir aramayla ZIP'i çıkarmak için 3. parti kütüphanesi mi? WTF – Kutzi

cevap

0

Öyle görünüyor: kütüphane oldukça büyük ve ihtiyacım daha geniş kapsamlı olduğu için, https://truezip.dev.java.net/manual-6.html#Copying

Bu ideal bir durum değil (ve aynı zamanda java.io.File örneklerini de işleyen sınıflarda kullanım için File olarak da adlandırılan java.io.File alt sınıfları etrafında organize olmak gibi bazı tuhaf ve kafa karıştırıcı ayrıntıları ile!).

En azından sınıftaki kod satırlarının çoğunun sınıfın sorumluluğu ile ilgisi olmadığı veya projeyle ilgili olmayan karmaşık bir yardımcı program sınıfını sürdürdüğü bir durumda olmak zorunda değilim. modülün amacı.

Bu, deneyimli geliştiricilerin Java'dan Ruby'ye geçişlerinin temel nedenini gösteren tipik bir örnek olduğunu düşünüyorum. Java'daki kütüphanelerin bolluğuna rağmen, pek çoğu, basit operasyonların daha uzmanlaşmış olanlar olarak gerçekleştirilmesinin zorlaşmasını sağlayacak şekilde zayıf bir şekilde tasarlanmıştır. Teknoloji uzmanları tarafından, her detayı ve olanakları ortaya koymak için gündelik görevleri basitleştirmekten daha hevesli gibi görünüyorlar. Apache ortakları, sınıfınızı sınıfın iş amacına bağlı olmayan kod çizgilerinden, özellikle döngülerden ve koşullardan kurtarmayı amaçlayan kütüphaneler yaratmanın onurunu hak ediyor.

+0

hmm. tam beklediğim gibi çalışmıyor. zip içindeki kavanoz dosyalarına yeniden girer ve kodları kullanmamıza rağmen onları da çıkarır. Aklımda olmayan şey değil. – eirikma

+0

TrueZIP 7'yi deneyin. Artık sınıf TFile olarak adlandırılıyor ve API'si temiz ve üretken. Ruby yaklaşımını seviyorsanız, bunu da beğenebilirsiniz. –

1

Eh, java.util.zip sen çok straighforward şekilde ben

package com.den.frontend; 

ithalat java.util kazıp başardı

+0

Biliyorum, ama demek istediğim bu değildi. Aşağıdaki jsshah tarafından cevaba yorum yapın. – eirikma

+1

Orada tek gömlekler bulamadım. Bir şey mi özledim @helios? –

+0

Hayır. Tek gömlekler, sadece çok geniş bir şekilde uygulayabileceğiniz araçlar, ne istenir. Bir zip dosyasını (girişleri) okuyun, her giriş için dir, açık dosya, içeriğe dökümü ve kapat. Sadece jsshah ne önerir ama belki biraz daha kompakttır (ve commons-fileupload'un 'Streams.copy'ünü kullanır). – helios

7

çok eski kod istediğini yapmak sınıfları vardır. ; import java.util.zip.; import java.io. *; o TrueZip kitaplığı kullanarak İstediğimi yapmak mümkün gibi

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

teşekkürler, ikiniz de, ama demek istediğim bu değil. Zip girişlerini değiştirmek, gerekli dizinleri oluşturmak ve böylece std api'yi kullanmak mümkün olduğunu biliyorum. Tüm bunları programımda istemiyorum. Çok fazla kod: çirkin ve kafa karıştırıcı. Tüm bu şeyleri içerecek şekilde dosyaları açmak isteyen tüm programlar için gerekli olmamalıdır. Komut satırında yapacağınız gibi, bir arşivi açmak için tek satırlı bir komut istiyorum. ZipFile sınıfının unzipTo (dizin) yöntemine sahip olmadığına inanmak zor. Bunun yerine aynı şeyi yapmak için 50 satır gerektirir. API tasarımı için ne var? – eirikma

+1

hmm. Belki de bu deneyin: Runtime.getRuntime() exec (yeni bir String [] { "açmak", "-d" zipfile.getAbsolutePath(), destdir.getAbsolutePath(), }.); – eirikma

+0

Bir JavaClass kullanmanın avantajı taşınabilirliktir (yerel ikili dosyalar hakkında endişelenmenize gerek yok) – helios

6

Biliyorum, gösteriye oldukça geç kaldım, ama aynı şeyi arıyordum ve bunu google yoluyla buldum. Bulduğum en kolay yol, "unzip" ant görevidir. Bir dizin bu

benziyor için bir dosya halletmek için

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

kod içerecek şekilde java kaynağından (komple karınca proje oluşturmak için ProjectHelper gibi şeyler vardır) karmaşık karınca kurulum olmadan kullanabilirsiniz

org.apache.ant.compress.taskdefs.Unzip u = new Unzip(); 
u.setSrc(new File("<archive.zip>")); 
u.setDest(new File("<targetDir>")); 
u.execute();