2009-04-11 29 views
22

Digamos que tengo un archivo t.txt, un directorio t y otro archivo t/t2.txt. Si uso la utilidad Linux postal "zip -r t.zip t.txt t", aparece un archivo zip con las siguientes entradas en ellas (descomprimir -l t.zip):directorios en un archivo zip al usar java.util.zip.ZipOutputStream

Archive: t.zip 
    Length  Date Time Name 
--------  ----  ----  ---- 
     9 04-11-09 09:11 t.txt 
     0 04-11-09 09:12 t/ 
     15 04-11-09 09:12 t/t2.txt 
--------       ------- 
     24       3 files 

Si trato para replicar ese comportamiento con java.util.zip.ZipOutputStream y crear una entrada zip para el directorio, java arroja una excepción. Puede manejar solo archivos. Puedo crear una entrada t/t2.txt en el archivo zip y agregar usar el contenido del archivo t2.txt, pero no puedo crear el directorio. ¿Porqué es eso?

Respuesta

30

ZipOutputStream puede manejar directorios vacíos mediante la adición de una barra inclinada / después de que el nombre de la carpeta. Trate (from)

public class Test { 
    public static void main(String[] args) { 
     try { 
      FileOutputStream f = new FileOutputStream("test.zip"); 
      ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(f)); 
      zip.putNextEntry(new ZipEntry("xml/")); 
      zip.putNextEntry(new ZipEntry("xml/xml")); 
      zip.close(); 
     } catch(Exception e) { 
      System.out.println(e.getMessage()); 
     } 
    } 
} 
+3

Te equivocas Juan. Los archivos Zip manejan los directorios vacíos sin problemas. El truco es que debes poner una barra al final del nombre. –

6

puede añadir "/" al final del nombre de la carpeta. Simplemente use el siguiente comando:

zip.putNextEntry(new ZipEntry("xml/")); 
12

programa Java para Zip (carpetas contiene vacíos o los llenos)

public class ZipUsingJavaUtil { 
    /* 
    * Zip function zip all files and folders 
    */ 
    @Override 
    @SuppressWarnings("finally") 
    public boolean zipFiles(String srcFolder, String destZipFile) { 
     boolean result = false; 
     try { 
      System.out.println("Program Start zipping the given files"); 
      /* 
      * send to the zip procedure 
      */ 
      zipFolder(srcFolder, destZipFile); 
      result = true; 
      System.out.println("Given files are successfully zipped"); 
     } catch (Exception e) { 
      System.out.println("Some Errors happned during the zip process"); 
     } finally { 
      return result; 
     } 
    } 

    /* 
    * zip the folders 
    */ 
    private void zipFolder(String srcFolder, String destZipFile) throws Exception { 
     ZipOutputStream zip = null; 
     FileOutputStream fileWriter = null; 
     /* 
     * create the output stream to zip file result 
     */ 
     fileWriter = new FileOutputStream(destZipFile); 
     zip = new ZipOutputStream(fileWriter); 
     /* 
     * add the folder to the zip 
     */ 
     addFolderToZip("", srcFolder, zip); 
     /* 
     * close the zip objects 
     */ 
     zip.flush(); 
     zip.close(); 
    } 

    /* 
    * recursively add files to the zip files 
    */ 
    private void addFileToZip(String path, String srcFile, ZipOutputStream zip, boolean flag) throws Exception { 
     /* 
     * create the file object for inputs 
     */ 
     File folder = new File(srcFile); 

     /* 
     * if the folder is empty add empty folder to the Zip file 
     */ 
     if (flag == true) { 
      zip.putNextEntry(new ZipEntry(path + "/" + folder.getName() + "/")); 
     } else { /* 
       * if the current name is directory, recursively traverse it 
       * to get the files 
       */ 
      if (folder.isDirectory()) { 
       /* 
       * if folder is not empty 
       */ 
       addFolderToZip(path, srcFile, zip); 
      } else { 
       /* 
       * write the file to the output 
       */ 
       byte[] buf = new byte[1024]; 
       int len; 
       FileInputStream in = new FileInputStream(srcFile); 
       zip.putNextEntry(new ZipEntry(path + "/" + folder.getName())); 
       while ((len = in.read(buf)) > 0) { 
        /* 
        * Write the Result 
        */ 
        zip.write(buf, 0, len); 
       } 
      } 
     } 
    } 

    /* 
    * add folder to the zip file 
    */ 
    private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception { 
     File folder = new File(srcFolder); 

     /* 
     * check the empty folder 
     */ 
     if (folder.list().length == 0) { 
      System.out.println(folder.getName()); 
      addFileToZip(path, srcFolder, zip, true); 
     } else { 
      /* 
      * list the files in the folder 
      */ 
      for (String fileName : folder.list()) { 
       if (path.equals("")) { 
        addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, false); 
       } else { 
        addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip, false); 
       } 
      } 
     } 
    } 
} 
+3

Debería cerrar su * FileInputStream *. – CSchulz

+1

Totalmente, debe cerrar FileInputStream. Sin embargo, esto es muy bueno! – Phuong

+0

Una API improvisada: tiene un ** 'zipFiles (final String [] srcFolders, final String destZipFile)' ** para agregar varias carpetas a su archivo comprimido. Simplemente agregando un for-loop en el método 'zipFolder'. Las carpetas individuales y múltiples son realmente fáciles de agregar a un archivo zip con estos métodos. – Velth

9

Al igual que otros dijeron aquí para añadir directorio vacío añadir "/" al nombre del directorio. Preste atención NO a agregar File.separator (es igual a "\") que realmente agrega un archivo vacío al zip.

Me tomó un tiempo para entender lo que fue mi error - esperanza ahorro otra algún tiempo ...

Cuestiones relacionadas