CREACION DE FICHEROS ZIP: Implementación un compresor de ficheros ZIP.

En el artículo "DESCOMPRESION DE FICHEROS ZIP" se explicaba la manera de extraer archivos de un fichero comprimido ZIP.

En presente artículo pretende mostrar la manera de crear ficheros ZIP usando las clases java para compresión que proporciona el JDK, así como las consideraciones a tener en cuenta para un resultado correcto.

Las clases del JDK que intervienen en la compresión de ficheros son varias aunque sólo tres de ellas nos interesan:

  • ZipEntry
  • ZipOutputStream
  • ZipException

ZipEntry es usada para representar una entrada de fichero comprimido. Esta clase nos permite incluso establecer el método de compresión del archivo a incluir.

ZipOutputStream es usado para crear un stream comprimido de salida.

ZipException representa la clase expecifica en caso de error en el proceso de compresión/descompresion.

El compresor

Para demostrar el uso de las clases crearemos un pequeño ejemplo consistente en una aplicación capaz de crear un fichero zip en el que podremos incluir los ficheros que creamos oportuno.

El programa consta de 4 clases:

  • jZipException: la excepción generada por la aplicación
  • zipFileFilter: clase usada en toolsZip para filtrado de nombres de archivo
  • jZip: clase que contiene los métodos para la creación de fichero ZIP
  • toolsZip: contienen los métodos para análisis y descomposición de nombre de ficheros. Notese que aunque en el artículo de descompresión se incluye una clase con el mismo nombre, no contienen los mismos métodos.
  • javaZip: es la clase que contiene el main
jZipException

import java.io.*;
import java.util.*;

public class jZipException extends Exception {
   public jZipException(String strError) {
      super(strError);
   }
}

La clase jZiException únicamente implementa el constructor al que se le pasa la cadena con el mensaje de error.

jUnzip

import java.io.*;
import java.util.*;
import java.util.zip.*;

public class jZip {
static public boolean _compressFiles(String fileNameZip, Vector filesSrc, 
              Vector filesName) throws jZipException {
   FileInputStream fis = null;
   FileOutputStream fos = null;
   ZipOutputStream zos = null;
   if (filesSrc == null || filesSrc.size() == 0)
      return false;
   if (filesName == null || filesName.size() != filesSrc.size()) 
      //mismo vector de nombres
      filesName = filesSrc;
   try {  
      byte buffer[] = new byte[4048];
      int lenToWrite;
      if (toolsZip.existFileDir(fileNameZip)) {
         toolsZip.deleteFile(fileNameZip);
      }
      fos = new FileOutputStream(fileNameZip);    
      zos = new ZipOutputStream(fos);     
      for (int inx = 0; inx < filesSrc.size(); inx++) {
         fis = new FileInputStream((String)filesSrc.elementAt(inx)); 
         ZipEntry ze = new ZipEntry((String)filesName.elementAt(inx));
   System.out.println(filesSrc.elementAt(inx) + "-->" + filesName.elementAt(inx));
         zos.putNextEntry(ze);  
         while ((lenToWrite=fis.read(buffer)) != -1) {
            zos.write(buffer,0,lenToWrite);
         }
         fis.close();   
         fis = null;
      }
    }
    catch (Exception e) {
       System.err.println("Error -> "+e.getMessage());
       throw  new jZipException("[compressFile]"+ e.getMessage());
    }
    finally {
       try {
          if (fis != null)
             fis.close();
          if (zos != null ) {
             zos.closeEntry();
             zos.close();     
          } 
       }
       catch(Exception e) {
          throw  new jZipException("[compressFile]"+ e.getMessage());
       }    
    }
    return true;
}
static public boolean compressFiles(String file, String args[]) 
   throws jZipException {

   Vector filesSrc= new Vector();
   Vector filesName = new Vector();
   Vector v = null;
   int start= 1;
   for (int n = start; n<args.length;n++) {
      String name;
      String path;
      String ext;
      name= toolsZip.getName(args[n]);
      path= toolsZip.getPath(args[n]);
      ext = toolsZip.getExtension(args[n]);
      v = toolsZip.getFilesList(path, name, ext);
      for (int m = 0;m<v.size();m++) {
         String aux;
         aux = ((File)v.elementAt(m)).getPath();
         filesSrc.addElement(((File)v.elementAt(m)).getPath()) ;
         filesName.addElement(((File)v.elementAt(m)).getPath().replace('','/')) ;
      }
    }
    return _compressFiles(file, filesSrc, filesName);
}
}

La Clase jZip es la que encargada de realizar la compresión con el método compressFiles. Este método tiene dos parámetros:

  • String fileName: es el nombre del fichero ZIP a crear
  • String args[]: es el array de strings con todos los ficheros a incluir. Acepta el comodín asterisco (*) y el path.

El método compressFiles llama a su vez a _compressFiles que tiene los siguientes parámetros:

  • String fileNameZip: es el nombre del fichero ZIP a crear
  • Vector filesSrc: es el vector que contiene el origen de los ficheros a comprimir
  • Vector filesName: es el vector que contiene el nombre con el que se almacenan los ficheros a comprimir

Por cada fichero a comprimir se crea una entrada (instancia) de ZipEntry que se añade al stream de salida de tipo ZipOutpuStream asociada al fichero Zip a crear y se copia los ficheros en el output stream proporcionado.

En el caso de que haya algún problema se lanzará una Excepción de tipo jZipException

zipFileFilter

import java.io.*;
import java.util.*;

public class zipFileFilter implements java.io.FilenameFilter {
   private String name;
   private String extension;
   private boolean caseSensitive; 
public zipFileFilter (String namefile, String ext, boolean casesensitive) {
   caseSensitive = casesensitive;
   if (caseSensitive) { // for unix enviroments
      name = namefile; 
      extension = ext;
   } 
   else {
      name = namefile.toUpperCase();
      extension = ext.toUpperCase();
   }    
}
  
public boolean accept(java.io.File dir, String fileName) {
   if (name.equals("*") && extension.equals("*")) //this ignore the case letter
      return true;
   if (name.equals("*")) {
      if (caseSensitive) {    
         if(! fileName.endsWith("." + extension)) return false;
      } 
      else {
         if(! fileName.toUpperCase().endsWith("." + extension)) return false;     
      }       
      return true;
   }   
   if (extension.equals("*")) {//this ignore the case letter
      if (caseSensitive) {    
         if (!fileName.startsWith(name)) return false;  
      } 
      else {
        if(! fileName.toUpperCase().startsWith(name)) return false;
      }     
      return true;      
   }  
   if (caseSensitive) {   
      if (!fileName.startsWith(name)) return false;
         if (!fileName.endsWith("." + extension)) return false;
   }
   else {
      if (! fileName.toUpperCase().startsWith(name)) return false;
         if (! fileName.toUpperCase().endsWith("." + extension)) return false;      
      }  
      return true;
  }
}

La Clase zipFileFilter implementa el interficie FilenameFilter para filtrado de nombres de ficheros, usado en la clase toolsZip.

toolsZip

import java.io.*;
import java.util.*;

public class toolsZip {
static public String getPath(String name) {
   String tmp = new File(name).getName();
   String tmp0 = new File(name).getPath();
   int len = tmp0.length() > tmp.length() ? tmp0.length() - tmp.length():0;
   if (len >0)
      return tmp0.substring(0, len);
   return   "";
}
static public String getName(String name) {
   String tmp = new File(name).getName();
   String ret = "";
   StringTokenizer st = new StringTokenizer(tmp, ".");
   while(st.hasMoreTokens()) {
      ret = st.nextToken();
   }      
   if (ret.length()!= 0) {
      int len = tmp.length()-ret.length()-1;
      if (len >0)
         return tmp.substring(0, len);
      if (tmp.startsWith(".")) 
         return "";  
   }  
   return tmp;
}
static public String getExtension(String name) {
   String tmp = new File(name).getName();
   String ret = "";
   if (tmp.length()==0)
      return ret;
   StringTokenizer st = new StringTokenizer(tmp, ".");
   while(st.hasMoreTokens()) {
      ret = st.nextToken();
   }      
   if (ret.length()!= tmp.length())
      return tmp.substring(tmp.length()-ret.length());
   return ""; 
}
  
static public Vector getFilesList(String sourcePath, String name, String ext){
   Vector v = new Vector();
   String fullPathFile = null;    
   File filetmp = null;
   boolean existfile = false;
   String separador = File.separator;
   if (sourcePath == null) 
      sourcePath = "";
   if (sourcePath.endsWith(File.separator)) {
      if (sourcePath.length()>1)
         sourcePath = sourcePath.substring(0, sourcePath.length()-1);   
      else {    
         separador = "";
      }     
   }  
   if (sourcePath.length()==0)
      sourcePath =System.getProperty("user.dir", File.separator);
   File dir = new File(sourcePath);
   if (name == null) 
      name = "*";
   if (ext == null) 
      ext = "*";
   try {
      if (dir.exists()) {
         String[] files = dir.list(new zipFileFilter(name, ext, false));
         if (files.length != 0) {     
            for (int i = 0; i < files.length; i++) {                      
               if (files[i].equals(".") || files[i].equals(".."))
                  continue;
               fullPathFile  = sourcePath + separador + files[i];         
               filetmp = new File(fullPathFile);
               if (filetmp.isDirectory()) { // si es un directorio lo ignoramos
                  continue;
               }
               else {                 
                  v.addElement(filetmp);
               } 
            }
         }  
      }   
   }
   catch(SecurityException ee) {
      String str = "[getFilesList] " + ee.getMessage();;
      System.err.println(str);
   };
   return v;
} 

static public boolean deleteFile(String nameFile){
   File file = new File(nameFile);
   boolean ret = false;
   try {
      if (file.exists())              
         if (file.isFile()) {
            ret = file.delete();  
         }  
         else {
            String str = "[deleteFile] " + nameFile + "no es un fichero.";
            System.err.println(str);
            return false; 
         } 
    }
    catch(SecurityException ee) {
       String str = "[deleteFile] " + ee.getMessage();
       System.err.println(str);
       return false;  
    };
    return ret;
}
static public boolean existFileDir(String nameFile) {
   File file = new File(nameFile);
   boolean ret = false;
   try {
      if (file.exists())              
         return true;
   }
   catch(SecurityException ee) {
      String str = ee.getMessage();
      System.err.println(str);
   };
   return ret;
}
}

La Clase toolsZip contiene métodos para la manipulación de ficheros y directorios:

  • getPath obtiene el path de fichero de una cadena.
  • getName obtiene el nombre de fichero de una cadena.
  • getExtension obtiene la extensión de fichero de una cadena.
  • getFilesList obtiene todos los archivos con el patrón marcado por los parámetros sourcePath, name y ext.
  • deleteFile borra el fichero especificado por el parámetro nameFile.
javaZip

import java.io.*;
import java.util.*;

public class javaZip {
   public static void main(String args[]) {
      String file = "";
      if (args.length < 2 ){
         System.out.println("sintaxis: " +
            "javaZip  <nombre fichero ZIP> 
            <nombre fichero 1>[<nombre fichero 2>...<nombre fichero n>]");
         return;
      }
      file = args[0];
      try {
         jZip.compressFile(file, args);
      }
      catch(Exception e ) {
         System.out.println("ERROR:" + e.getMessage());
      }
   }
}

javaZip contiene el código que obtiene los parámetros y llama a jZip.compressFile

BIBLIOGRAFIA Y REFERENCIAS

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO

¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.