14 noviembre 2008

Comprimir y descomprimir archivos con ZipForge

Aunque hay muchos componentes de terceros para Delphi que comprimen y descomprimen archivos zip con total naturalidad hay que reconocer que muchos de ellos necesitan librerías DLL externas. Sin embargo el componente ZipForge permite manipular archivos zip sin ninguna librería adicional. Todo va dentro de nuestro ejecutable.

Este componente es comercial y se vende al precio de 49 € (sin el código fuente). Para probarlo podemos bajar una versión personal para uso no comercial desde su página web:

http://componentace.com/zip_component_zip_delphi_zipforge.htm


Lo bueno de este componente es que está disponible para todas las versiones de Delphi:

En mi caso me he bajado la versión para RAD Studio 2007, cuya instalación va comprimida en un archivo zip de 2,81 MB.

INSTALANDO EL COMPONENTE

Para instalarlo sólo hay que descomprimir el archivo y ejecutar Install.exe, para luego ir pulsando el botón Next hasta que finalice la instalación:


Lo bueno de esta instalación es que no hay que instalar paquetes DPK ya que lo hace automáticamente. Sólo hay que cerrar Delphi, volver a abrirlo y veremos este mensaje al arrancar:


Cuando compremos el producto y lo registremos desaparecerá este mensaje. Al crear o abrir un nuevo proyecto ya tenemos visible el componente ZipForge en la paleta de componentes:


COMPRIMIR ARCHIVOS CON ZIPFORGE

Insertamos el componente en el formulario y le ponemos en su propiedad name el nombre Zip para simplificar:


Supongamos que tengo en la carpeta D:\prueba estos tres archivos:


Para comprimir estos archivos en un solo archivo zip hacemos lo siguiente:

With Zip do
begin
FileName := 'd:\prueba\documentos.zip';
OpenArchive( fmCreate );
BaseDir := 'd:\prueba\';
TempDir := 'd:\prueba\';
AddFiles( '*.pdf' );
CloseArchive;
end;

Con FileName le hemos dicho como va a llamarse el archivo zip que vamos a crear. Después creamos el archivo con OpenArchive y le decimos con la propiedad BaseDir desde donde vamos a comprimir los archivos.

No es necesario decirle también la propiedad TempDir (directorio temporal de compresión/decompresión) aunque recomiendo utilizar el mismo directorio para que no deje archivos temporales en Windows en caso de que se interrumpa el proceso de compresión/descompresión.

Por último sólo hay que decirle mediante AddFiles los archivos que vamos a comprimir (admitiendo incluso *.*) y cerramos el archivo creado.

Esta sería una compresión de archivos normal pero tenemos muchas más opciones. Por ejemplo, le podemos poner una contraseña al archivo zip escribiendo esto antes del comando AddFiles:

Password := '1234';

Si queremos asegurarnos de que los archivos se han comprimido correctamente podemos ejecutar esto:

AddFiles( '*.*' );

try
TestFiles('*.*');
except
Application.MessageBox( 'Error al comprimir los archivos.',
'Atención', MB_ICONSTOP );
end;

CloseArchive;

Otra opción que podemos elegir es el nivel de compresión:

CompresionLevel := clMax;

Permite todos estos valores:

clMax -> es la que más comprime pero la más lenta
clNormal -> compresión normal
clFastest -> es la compresión más rápida pero la que menos comprime
clNone -> no comprime nada, sólo empaqueta los archivos.

Si queremos controlar el proceso de compresión con una barra de progreso tenemos que añadir este código en el evento OnFileProgress:

procedure TForm1.ZipFileProgress(Sender: TObject; FileName: WideString;
Progress: Double; Operation: TZFProcessOperation;
ProgressPhase: TZFProgressPhase; var Cancel: Boolean);
begin
if ProgressPhase = ppProcess then
ProgressBar1.Position := Round(Progress);
end;

Lo que contiene el valor Progress no es el incremento total de la compresión sino el porcentaje de cada archivo que está comprimiendo. Por lo tanto sería conveniente hacer esto antes de empezar:

ProgressBar1.Max := 100;

Por último y no menos importante, también nos permite comprimir archivos desde un stream, desde un buffer de memoria o una cadena de texto:

procedure AddFromStream(FileName: WideString; Stream: TStream;
CopyToBuffer: Boolean = True; Position: Integer = 0;
Count: Integer = 0; Attr: Integer = faArchive; DateTime: TDateTime = 0);

procedure AddFromBuffer(FileName: WideString; const Buffer; Count: Integer;
Attr: Integer = faArchive; DateTime: TDateTime = 0);

procedure AddFromString(FileName: WideString; Text: String;
Attr: Integer = faArchive; DateTime: TDateTime = 0);

Algo sin duda muy interesante para no tener que crear archivos intermedios.

CREANDO ARCHIVOS AUTOEJECUTABLES

Para comprimir un archivo y hacerlo autoejecutable debemos utilizar un ejecutable que trae predeterminado el componente ZipForge y que viene en el directorio:

\ComponentAce\ZipForge\SFXStub\SFXStub.exe

Esa ruta hay que indicársela antes de crearlo:

With Zip do
begin
FileName := 'd:\prueba\documentos.zip';
OpenArchive( fmCreate );
BaseDir := 'd:\prueba\';
TempDir := 'd:\prueba\';
AddFiles( '*.*' );
CloseArchive;
SFXStub := 'D:\CodeGear\RAD Studio\5.0\Componentes\ZipForge\SFXStub\SFXStub.exe';
MakeSFX( 'd:\prueba\documentos.exe' );
end;

Al hacer doble clic sobre el ejecutable nos pedirá la ruta de descompresión:


DESCOMPRIMIR ARCHIVOS CON ZIPFORGE

Descomprimir archivos es todavía más fácil que comprimirlos:

With Zip do
begin
FileName := 'd:\prueba\documentos.zip';
OpenArchive( fmOpenRead );
BaseDir := 'd:\prueba\';
TempDir := 'd:\prueba\';
ExtractFiles( '*.*' );
CloseArchive;
end;

Si nos fijamos en las propiedades que tiene el componente ZipForge en el inspector de objetos podemos configurar si queremos que cree carpetas al descomprimir (si las hay) o elegir por ejemplo si queremos sobrescribir archivos:


Un componente como este se hace casi imprescindible para dar a nuestros programas funcionalidades tales como crear copias de seguridad de bases de datos, descomprimir archivos de configuración en directorios remotos o incluso proteger nuestros gráficos y recursos dentro de un zip con contraseña para que no puedan ser utilizados por otro programador.

Pruebas realizadas en RAD Studio 2007.

Publicidad