Inicio > Delphi, Ejemplos, XE2 > Testeando XE2… (soporte nativo para ficheros ZIP)

Testeando XE2… (soporte nativo para ficheros ZIP)

miércoles, 14 de septiembre de 2011 Dejar un comentario Ir a comentarios
Share Button

ZIPFile   Otra de las nuevas funcionalidades que trae la versión de XE2 es el soporte para ficheros ZIP. No es que sea especialmente transcendental, pero en mi caso la he utilizado bastante en mis desarrollos y hasta ahora lo había tenido que hacer mediante componentes externos (he  probado varios paquetes).

   Para ello se ha añadido a la unit System.ZIP, todo lo necesario para el trabajo con este tipo de ficheros.

   En sistema de trabajo es bastante sencillo. Para trabajar con un fichero de este tipo tenemos que crear un objeto de la clase TZIPFile y abrirlo (utilizando la función Open). Tenemos diferentes modos de apertura dependiendo de las operaciones a realizar con el fichero (read,write o readwrite).

// Abrir un fichero
procedure Open(ZipFileName: string; OpenMode: TZipMode); overload;
procedure Open(ZipFileStream: TStream; OpenMode: TZipMode); overload;

Una vez abierto el fichero, podemos utilizar las operaciones básicas.
Extraer ficheros existentes dentro del archivo:

// Extraer un fichero sobre una ubicación
procedure Extract(FileName: string; Path: string = '';
                  CreateSubdirs: Boolean=True); overload;
procedure Extract(Index: Integer; Path: string = '';
                  CreateSubdirs: Boolean=True); overload;

O extraerlos todos:

// extraerlos todos hacia un directorio
procedure ExtractAll(Path: string = '');

Añadir ficheros a un archivo comprimido existente:

// Añadir ficheros a un archivo comprimido
procedure Add(FileName: string; ArchiveFileName: string = '';
              Compression: TZipCompression = zcDeflate); overload;

(esta tienen bastantes variantes sobrecargadas con diferentes parámetros)

Y también podemos comprobar la integridad de un fichero comprimido existente mediante la función IsValid (que en este caso está definida como función de clase).

class function IsValid(ZipFileName: string): Boolean; static;

No son todas las funciones, pero sí las básicas; También hay algunas más definidas como procedimientos de clase, que nos permiten realizar operaciones de forma más sencilla y/o rápida.

Para ponerlo en práctica y probarlo he realizado un sencillo ejemplo que incluye las operaciones básicas; Y podéis comprobar que con pocas líneas es fácil hacer casi todo lo que se espera de estos ficheros.

 

TestZIPFile

Por ejemplo, el código para extraer todo el contenido sobre un directorio seleccionado es el siguiente:

procedure TForm3.ActionExtractExecute(Sender: TObject);
var
  b:boolean;
  DirOut:String;
begin
  // El nombre es vacío?
  if (zipFileName = '') then begin
    // Abrir uno
    ActionOpen.Execute;
    // Correcto?
    if (zipFileName = '') then begin
      Exit;
    end;
  end;
 
  // Es Valido
  b := xf.IsValid(zipFileName);
 
  // no correcto?
  if not (b) then begin
    MessageDlg('Error al abrir el fichero. Parece que es' +
               ' incorrecto o está corrupto.',
               mtError, [mbOK], 0);
    exit;
  end;
 
  // Extraer  // Path de salida
  b := SelectDirectory('Seleccione el directorio para extraer ficheros',
                       '', DirOut);
  if (b) then begin
    // protección
    try
      // Extraer al directorio seleccionado
      xf.Open(zipFileName, zmRead);
      xf.ExtractAll(DirOut);
      xf.Close;
      MessageDlg('La extracción se ha producido correctamente',
        mtInformation, [mbOK], 0);
    except
      MessageDlg('Se ha producido un error al extraer los ficheros.',
        mtError, [mbOK], 0);
    end;
  end;
end;

El código para añadir uno o varios ficheros seleccionados en un OpenDialog sería similar a este:

procedure TForm3.ActionAddFilesExecute(Sender: TObject);
var
  b:Boolean;
  i:integer;
begin
 
  // No está creado?
  if not Assigned(xf) then begin
    // Si no lo está lo creamos
    ActionNuevoZIPExecute(nil);
  end;
  // Selecciconar ficheros a añadir
  b :=  OpenDialog1.Execute;
  if (b) then begin
    // Abrirlo
    xf.Open(zipFileName, zmReadWrite);
 
    // Para 1 fichero
    //     xf.Add(OpenDialog1.FileName);
 
    // Para n ficheros
    for i := 0 to (OpenDialog1.Files.Count - 1) do begin
      xf.Add(OpenDialog1.Files[i]);
    end;
    // cerrar
    xf.Close;
  end;
  // Actualizar la pantalla
  _UpdateFiles();
end;

Para cada fichero que hay incluído en un archivo ZIP contamos con una estructura que nos permite acceder a todas la información de forma rápida. Definido como packed record, en System.ZIP podéis encontrar la definición completa y la documentación de esta estructura:

Podéis revisar el código completo del ejemplo; Está disponible aquí y podéis descargarlo junto con el fichero  compilado.

[SOURCES + BIN]

Un saludo.

Vota este post
Categories: Delphi, Ejemplos, XE2 Tags: , , ,
Subscribe
Notify of
guest

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

16 Comments
Inline Feedbacks
Ver todos los comentarios
Ñuño Martínez
13 years ago

No está mal, pero es incómodo. Prefiero el soporte para TAR y GZip que tiene Free Pascal (http://lazarus-ccr.sourceforge.net/fpcdoc/fcl/libtar/ y http://lazarus-ccr.sourceforge.net/fpcdoc/fcl/zstream/ respectivamente), que te permiten acceder al contenido de paquetes .tar y .tar.gz usando TStream, sin tener que extraer previamente los archivos.

Estaría bien que Delphi lo incluyera, en especial si realmente quiere hacerse un hueco en los sistemas POSIX (creo que MacOS también tiene soporte nativo para TAR y GZip)

Ñuño Martínez
13 years ago

Amigo, si la clase tiene métodos para acceder a un archivo concreto para leerlo con un TStream, entonces mi queja es menor. Y si también permite insertar datos del mismo modo, pues entonces grito todavía menos.

Sólo queda, entonces, lo del formato, Pero eso ya es otro tema. En última instancia siempre se puede adaptar las clases de la FCL a Delphi, ¿no?

German
German
13 years ago

Creo que la única pega que pondría sobre esta clase sería los eventos… ya que no dispone de ninguno y es imposible mostrar una barra de proceso, totalmente necesaria en mi opinión, para trabajar con archivos grandes.

Salu2.

Alejandro
Alejandro
11 years ago

Amigo Neftalí, que paquetes has probado para el manejo de archivos comprimidos. Necesito manejar esos archivos usando la versión 10 de Delphi.

Espero que me puedas recomendar alguno que sea relativamente bueno y en lo posible gratis.

joan
joan
11 years ago

la fecha no te la pone bien alguien podra arreglarlo?? y que te de la medida en mega Bytes plis

Juan Labrador
Juan Labrador
10 years ago

Hola:
Tengo un problema que espero me puedas ayudar. He hecho un programita para copiar ficheros en ZIP y funciona muy bien. El problema es que sí el fichero generado es mayor de 4 GB da un error al intentar abrirlo.
Cuando abro el fichero con 7-zip veo en las propiedades de cada fichero que aparece Host OS: FAT. Por el contrario, sí creo un fichero directamente (enviar a carpeta comprimida en zip) el Host OS: aparece como NTFS.
He indagado el fichero System.Zip.pas y creo que tiene que ver con LocalHeader.MadeByVersion que debería ser 10 (NTFS).
Gracias

Juan Labrador
Juan Labrador
10 years ago

@Germán Estévez
Muchas gracias por tu rápida respuesta. El problema es ese seguro pero no veo cómo decir que sea NTFS. En mi desesperación he compilado incluso una versión 64 y ejecutada en un Server 2008 pero también los hace FAT.
No se sí podria «rehacer» System.Zip.dcu editando System.Zip.pas y forzar el valor a 10.

Juan Labrador
Juan Labrador
10 years ago

Tengo la variable Fichero como TZipFile
Para añadir ficheros creo primero una lista de ficheros en un listbox (Ficheros) y luego hago un try para añadirlos uno a uno con
Fichero.Add(Ficheros.Items[J],Ficheros.Items[J],zcStored);
Así funciona bien pues de otro modo incluye todos en el raiz del fichero zip
El problema es que Fichero.FileInfo[J].MadeByVersion es de solo lectura y siempre los comprime como FAT, limitando el tamaño del archivo comprimido a 4 GB

Juan Labrador
Juan Labrador
10 years ago

Buscando he visto el enlace http://www.gzip.org/#faq10
Tal vez sea este el problema. Yo tengo la versión X3, puede que la X5 lo tenga solucionado.

16
0
Would love your thoughts, please comment.x
()
x