Boletín Pascal #5
INDICE
1. UNAS PALABRAS DEL EDITOR
2. FREE PASCAL
3. DELPHI ZIP
a) ¿Dónde obtenerlo?
b) Instalación
c) Probando la demo
d) ¿Cómo funciona?
1) Creando un nuevo archivo
2) Agregando ficheros a un archivo
3) Agregando ficheros a un archivo en múltiples volúmenes
4) Borrando ficheros de un archivo
5) Extrayendo ficheros de un archivo
6) Probando un archivo
7) Interceptando los mensajes
8) Listando los ficheros guardados en un archivo
________________________________________________________________________
1. UNAS PALABRAS DEL EDITOR
Nuestro nuevo sitio web ya está funcionando... o al menos debería! ;)
http://www.latiumsoftware.com/es/
Es lo mismo de antes, nada nuevo por ahora, pero este mes probablemente
comenzaremos a agregar material más o menos continuamente si podemos.
Los mantendremos informados.
En el último número escribimos wwww en vez de www en la dirección de
nuestro sitio, así que si no pudieron entrar al sitio, ahora saben por
qué! ;) Ups! Gracias a Alejandro que nos indicó este error.
Saludos,
Ernesto De Spirito
eds2008 @ latiumsoftware.com
________________________________________________________________________
JfControls Lib. Multilenguaje. Multiapariencia. Skins. Privilegios. Más
de 40 componentes integrados y personalizables. Múltiples problemas de
programación resueltos. Administración centralizada de recursos. Para
Delphi 3-2006 y C++ Builder 3-6. http://www.jfactivesoft.com/spindex.htm
________________________________________________________________________
2. FREE PASCAL
La versión 1.00 de este compilador pascal fue lanzada oficialmente en
Julio pasado y se espera que de a poquito comience a ser incluido en
muchas distribuciones de Linux. Está disponible como paquetes RPM,
.deb y .tar.gz. Pero Free Pascal no es sólo para Linux puesto que
también está disponible para DOS (requiere el GO32 extender), Windows de
32 bits, OS/2 (requiere el EMX extender) y Amiga (Versión 0.99.5).
Si desea bajarlo, siga este link: http://www.freepascal.org/sdown.html
Le sugerimos que elija un mirror porque el sitio principal por lo
general está muy lento.
________________________________________________________________________
3. DELPHI ZIP
Es un conjunto de componentes freeware para Delphi y una aplicación de
ejemplo (con código fuente completo incluido) que accede a archivos ZIP
usando las DLLs ZIPDLL y UNZDLL del proyecto Info-Zip. Funcionan en
todas las versiones de Delphi de 32 bits (de la 2 a la 5).
a) ¿Dónde obtenerlo?
====================
Está disponible en:
BCB and Delphi Freeware Zip Components
http://www.geocities.com/SiliconValley/Orchard/8607/
http://members.tripod.lycos.nl/Vleghert/
Yo descargué los siguientes archivos:
* Delphi Zip 1.6L beta release (360K)
http://www.geocities.com/SiliconValley/Orchard/8607/beta/dz-del160.zip
http://members.tripod.lycos.nl/Vleghert/beta/dz-del160.zip
* TZipMaster 1.6L Archivo de ayuda (81K)
http://www.geocities.com/SiliconValley/Orchard/8607/beta/zipmst16.zip
http://members.tripod.lycos.nl/Vleghert/beta/zipmst16.zip
El primer archivo tiene todo, excepto la ayuda del componente TZipMaster
y el código fuente de las DLLs:
* Código fuente de ZipDll y UnZDll para BCB 3 o BCB 4 (241K)
http://www.geocities.com/SiliconValley/Orchard/8607/dz-dllsrc15.zip
No lo descargué porque son para C++ Builder. Las DLLs están incluidas en
el archivo principal (dz-del160.zip) y también hay versiones optimizadas
disponibles, como ésta:
* Pentium DLLs. Compiladas con BCB 4 optimizadas para Pentium (129K)
http://www.geocities.com/SiliconValley/Orchard/8607/pendll15.zip
b) Instalación
==============
1) Descomprima dz-del160.zip en un directorio temporal y ejecute el
archivo dz-del160.exe para instalar. Le solicitará el directorio de
instalación. Yo elegí "C:\Delphi\Zip", pero puede extraerlo donde
quiera (simplemente sustituya "C:\Delphi\Zip" por su camino).
2) Copia o mueva estos ficheros a su directorio Windows\System:
C:\Delphi\Zip\DLL\*.DLL y C:\Delphi\Zip\SFX\*.BIN
3) Ahora debería copiar o mover los ficheros "C:\Delphi\Zip\VCL\*.*" a
un directorio en la ruta de la VCL, o incluir "C:\Delphi\Zip\VCL"
en su ruta de la VCL (en Delphi 5 elija Environment Options del menú
Tools y agregue este directorio a Library Path y Browsing Path).
4) Instale los componentes de la VCL. ¿Cómo? ¡Es el ABC! ¡Ya debería
saberlo! :) Está bien, inicie Delphi 5. Elija Close All del menú File
y luego Install Component del menú Component. Haga click en Browse
para seleccionar las unidades y seleccione todos los archivos *.pas
en el directorio "C:\Delphi\Zip\VCL" (o donde haya puesto esos
archivos) y haga clic en Abrir y luego OK para compilar. Finalmente
cierre el paquete y guárdelo cuando se le pregunte.
Si tiene una versión anterior de Delphi, siga las instrucciones que
se proveen en "C:\Delphi\Zip\Install.txt".
5) Instale los archivos de ayuda. ¿Cómo? ¡Es el ABC! ¡Ya debería
saberlo! :) Está bien, descomprima el archivo zipmst16.zip y mueva
los dos ficheros al directorio de la ayuda de Delphi (por ejemplo
"C:\Archivos de programa\Borland\Delphi5\Help"). Edite delphi5.cnt y
agregue estas dos líneas con las otras:
:Index ZipMaster Component Help=ZipMstr.hlp
:Include ZipMstr.cnt
Elimine los archivos delphi5.GID, delphi5.FTS y delphi5.FTG.
Esto también funciona con Delphi 3 y 4 (sólo sustituya el "5" de
arriba por su número de versión). Si tiene Delphi 2 y desea integrar
los archivos de ayuda, puede construir un archivo .kwf. Los fuentes
están disponibles para descargar:
* Fuentes del archivo de ayuda (98K)
http://www.geocities.com/SiliconValley/Orchard/8607/dz-hlpsrc15.zip
http://members.tripod.lycos.nl/Vleghert/
c) Probando la demo
===================
Abra el proyecto "C:\Delphi\Zip\Demo1\ZipDemo1.dpr" e intente compi-
larlo. Cuando lo hice, obtuve el siguiente mensaje de error:
[Fatal Error] mainunit.pas(632): Internal error: C3517
Este es un error del compilador y lo estoy reportando a Borland. Ya
aislé el problema y aparente ocurre cuando está activada la optimización
(predeterminado) y uno convierte explícitamente una propiedad de un
objeto (no una variable o constante) de tipo Int64 a Int64. Puede no
ocurrir en su versión/build de Delphi, pero si lo hace, habría dos
soluciones.
1) Apague las optimizaciones alrededor del procedimiento
ZipMaster1Progress:
{$OPTIMIZATION OFF}
procedure TMainform.ZipMaster1Progress(Sender: TObject...
...
end;
{$OPTIMIZATION ON}
2) O (mejor aún) quite las conversiones innecesarias a Int64:
// Step := Integer(Int64(TotalProgress1) * Int64(10000)
// div Int64(TotalSize1));
Step := Integer(TotalProgress1 * 10000 div TotalSize1);
// Step := Integer(Int64(TotalProgress2) * Int64(10000)
// div Int64(TotalSize2));
Step := Integer(TotalProgress2 * 10000 div TotalSize2);
Ahora ejecute el programa y haga clic en el botón "Open Zip". Seleccione
un archivo ZIP y haga clic en "Open". ¿Ahora qué? Si obtiene una
excepción de tipo EConvertError, no se preocupe: no es un error, es una
característica! ;) Esta vez es verdad porque TSortGrid usa excepciones
para determinar el tipo de datos la columna para realizar el ordena-
miento. Así que haga clic en OK y deje que la aplicación siga corriendo
(presione F9). Tendrá que hacerlo tres veces. Si no desea ver esos
errores en el futuro, vaya a Tools / Debugger Options / Language
Exceptions y desmarque la casilla de verificación "Stop on Delphi
Exceptions". En versiones anteriores de Delphi creo que se llamaba "Break
on Exceptions" o algo parecido, y estaba ubicada en otro lugar...
d) ¿Cómo funciona?
==================
Todo el trabajo lo realizan las DLLs, y el componente TZipMaster provee
una linda interfaz de programación para trabajar con estas DLLs, así que
no tenemos que preocuparnos por llamar a las APIs directamente, releván-
donos de un montón de detalles.
La aplicación demo es bastante completa y muestra toda la funcionalidad
básica del componente TZipMaster. Puede hecharle una mirada al código y
usar el archivo de ayuda integrado para aprender más acerca del uso de
este componente. Para ayudarle a entenderlo mejor, hemos decidido
construir una aplicación demo alternativa, que será muy simple, pensando
en proveerle un inicio rápido en cómo agregar capacidades mínimas de
manejo de Zips a su aplicación (para propósitos de copia de seguridad,
por ejemplo), en vez de construir una utilidad de compresión (como
WinZip o Power Archiver).
Para comenzar, elegimos New Application del menú File. Luego editamos el
fichero de programa y agregamos una directiva de recursos ($R) para
cargar los mensajes (están disponibles en varios idiomas):
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
{$R ZipMsgUS.RES} // Carga los mensajes en inglés
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Note que esto sólo afectará los mensajes generados por el componente,
no por las DLLs (que estarán en inglés). Desafortunadamente no hay
archivo de mensajes en español...
Ahora agregamos un componente TZipMaster al formulario y lo llamamos
Zip para darle un nombre más corto. Antes de comenzar el trabajo real
cargaremos las DLLs en memoria cuando se crea el formulario, y las
descargaremos cuando se cierre. No es necesario hacerlo porque
TZipMaster maneja esto automáticamente, cargando y descargando las
bibliotecas como sea necesario, pero esto puede significar una penalidad
en el rendimiento (consume tiempo), así que decidimos hacerlo por
nuestra cuenta:
procedure TForm1.FormCreate(Sender: TObject);
begin
Zip.Load_Zip_Dll;
Zip.Load_Unz_Dll;
end;
procedure TForm1.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Zip.Unload_Zip_Dll;
Zip.Unload_Unz_Dll;
end;
Las bibliotecas ocupan memoria cuando están cargadas, así que esta no es
necesariamente la mejor táctica tampoco, pero es mejor que cargarlas y
descargarlas cada dos por tres. El problema ahora es que la carga del
formulario toma más tiempo, así que quizás la mejor solución sea cargar
las DLLs la primera vez que se usan y descargarlas cuando deje de
usarlas (por ejemplo cuando se cierra el formulario), pero le dejamos
esto a usted. :-)
1) Creando un nuevo archivo
---------------------------
Para mostrar cómo crear un nuevo archivo Zip colocamos un botón en el
formulario (lo hemos llamado CreateZip), y en su evento Click
escribimos:
procedure TForm1.CreateZipClick(Sender: TObject);
const
ZipArch: string = 'C:\Temp\Test.zip';
begin
if FileExists(ZipArch) then
if MessageDlg('"' + ZipArch + '" ya existe. ¿Sobreescribir?',
mtConfirmation, [mbYes, mbNo], 0) = mrYes then
DeleteFile(ZipArch)
else
exit;
Zip.ZipFilename := ZipArch;
if Zip.ZipFilename = '' then begin
ShowMessage('No se pudo crear "' + ZipArch + '"!');
exit;
end;
Zip.AddOptions := [];
Zip.FSpecArgs.Add('Project*.*');
try
Zip.Add;
ShowMessage('¡Archivo Zip creado exitosamente!');
except
ShowMessage('No se pudo crear "' + ZipArch + '"!');
end;
end;
Primero preguntamos si el archivo ya existe, y si es así solicitamos
confirmación para sobreescribirlo. En caso afirmativo borramos el
archivo existente para que luego, cuando agreguemos ficheros al archivo,
éste se cree automáticamente. El método Add es el que realiza todo el
trabajo, pero antes que podamos invocarlos debemos hacer algunos
preparativos:
a) Establecer el nombre del archivo Zip en la propiedad ZipFilename
b) Establecer las opciones para agregar los ficheros (por ejemplo
podemos explorar directorios recursivamente, encriptar los ficheros
y otras cosas más).
c) Establecer los ficheros que serán agregados en la propiedad
FSpecArgs (un objeto TStringList).
2) Agregando ficheros a un archivo
----------------------------------
Ya hemos visto cómo agregar ficheros, pero aquí va otro ejemplo. Primero
colocamos un nuevo botón en el formulario y lo nombramos AddToZip, y en
su evento Click escribimos:
procedure TForm1.AddToZipClick(Sender: TObject);
const
ZipArch: string = 'C:\Temp\Test.zip';
begin
Zip.ZipFilename := ZipArch;
if Zip.ZipFilename = '' then begin
ShowMessage('¡No se pudo abrir "' + ZipArch + '"!');
exit;
end;
Zip.AddOptions := [AddUpdate];
Zip.FSpecArgs.Add('*.d*');
Zip.FSpecArgs.Add('Unit1.pas');
try
Zip.Add;
ShowMessage('Ficheros agregados!');
except
ShowMessage('No se pudieron agregar los ficheros!');
end;
end;
Este ejemplo es similar al anterior, excepto que hemos usado la opción
AddUpdate para decirle al método Add que si los ficheros que estamos
agregando ya se encuentran en el archivo, no deberían ser reemplazados a
menos que sean más recientes, pero los ficheros que no existen en el
archivo sí serán agregados. AddFreshen es como AddUpdate, pero no agrega
nuevos ficheros al archivo. El Add 'estándar' (si no se establece
ninguna opción) agregará o reemplazará ficheros incondicionalmente.
AddMove es como el Add standard, pero borra los ficheros del disco
después que han sido agregados.
3) Agregando ficheros a un archivo en múltiples volúmenes
---------------------------------------------------------
Para separar (span) un archivo en múltiples partes llamadas volúmenes,
simplemente incluimos AddDiskSpan en AddOptions. Para probar el
siguiente ejemplo, agregue un botón llamado Span en el formulario y
genere su evento Click:
procedure TForm1.SpanClick(Sender: TObject);
const
ZipArch: string = 'C:\Temp\SpanTest.zip';
begin
Zip.ZipFilename := ZipArch;
if Zip.ZipFilename = '' then begin
ShowMessage('¡No se pudo abrir "' + ZipArch + '"!');
exit;
end;
Zip.AddOptions := [AddDiskSpan];
Zip.KeepFreeOnDisk1 := 10000;
Zip.MaxVolumeSize := 100000;
Zip.FSpecArgs.Add('*.*');
try
Zip.Add;
ShowMessage('Ficheros agregados!');
except
ShowMessage('No se pudieron agregar los ficheros!');
end;
end;
Al separar el archivo en múltiples discos, establezca MaxVolumeSize a 0
y el tamaño del diskette será detectado automáticamente. Estableciendo
esta propiedad a otro valor forzará que las partes del archivo
(volúmenes) no sean más grandes que el valor que especifique (en bytes).
Esto es útil al dividir el archivo en el disco duro. Use KeepFreeOnDisk1
para establecer el número de bytes a dejar libres en el primer volumen.
En el ejemplo anterior, el tamaño del volumen es 100,000 bytes y hemos
requerido 10,000 bytes libres en el primer volumen, así que el tamaño
del primer volumen no excederá los 90,000 bytes.
4) Borrando ficheros de un archivo
----------------------------------
Para borrar un fichero o conjunto de ficheros del archivo podemos usar
el método Delete. Para ver un ejemplo, agregue un botón llamado
DeleteFromZip al formulario y genere su evento Click:
procedure TForm1.DeleteFromZipClick(Sender: TObject);
const
ZipArch: string = 'C:\Temp\Test.zip';
begin
Zip.ZipFilename := ZipArch;
if Zip.ZipFilename = '' then begin
ShowMessage('¡No se pudo abrir "' + ZipArch + '"!');
exit;
end;
Zip.FSpecArgs.Add('*.c*');
Zip.FSpecArgsExcl.Add('*.cfg');
try
Zip.Delete;
ShowMessage('Ficheros agregados!');
except
ShowMessage('No se pudieron agregar los ficheros!');
end;
end;
En este ejemplo hemos introducido la propiedad FSpecArgsExcl, una
StringList que contiene los nombres de los ficheros a excluir de la
operación (en este caso Delete). En el ejemplo de arriba, todos los
ficheros que concuerden con el patrón *.c* pero no *.cfg serán
borrados del archivo.
5) Extrayendo ficheros de un archivo
-------------------------------------
Esta operación es realizada por el método Extract. Para ver un ejemplo,
agregue un botón llamado ExtractFromZip al formulario y genere su
evento Click:
procedure TForm1.ExtractFromZipClick(Sender: TObject);
const
ZipArch: string = 'C:\Temp\Test.zip';
var
CurrentDir: string;
begin
Zip.ZipFilename := ZipArch;
if Zip.ZipFilename = '' then begin
ShowMessage('¡No se pudo abrir "' + ZipArch + '"!');
exit;
end;
CurrentDir := GetCurrentDir;
ChDir(ExtractFilePath(ZipArch));
Zip.ExtrOptions := [ExtrOverWrite, ExtrUpdate];
try
Zip.Extract;
ShowMessage('Ficheros extraídos!');
except
ShowMessage('No se pudieron extraer ficheros!');
end;
ChDir(CurrentDir);
end;
La carpeta destino es el directorio de trabajo actual, así que debe-
ríamos cambiarlo (usando el procedimiento ChDir) si queremos que sea
otro distinto. Previamente "guardamos" el directorio actual así podemos
restaurarlo más tarde. En el ejemplo usamos la carpeta donde está
localizado el archivo Zip ('C:\Temp'). Puesto que no especificamos los
ficheros a procesar en FSpecArgs, se extraerán todos los ficheros del
archivo.
Puede especificar algunas opciones de extracción en la propiedad
ExtrOptions. El método de extracción predeterminado sólo extraerá
ficheros si no existen en el disco. Si desea sobreescribir ficheros
existentes use la opción ExtrOverWrite (equivalente al Add estándar).
Puede conbinarlo con ExtrUpdate (equivaldría a AddUpdate) o con
ExtrFreshen (equivaldría a AddFreshen). Puede usar la opción
ExtrDirNames para recrear los caminos relativos guardados en el archivo
(los caminos se guardan usando la opción AddDirNames con el método Add).
6) Probando un archivo
----------------------
Para verificar la integridad de un archivo Zip use el método Extract con
la opción ExtrTest y luego compruebe el valor de la propiedad ErrCode.
Para verlo funcionando, agregue un botón llamado TestZip a su formulario
y genere su evento Click:
procedure TForm1.TestZipClick(Sender: TObject);
const
ZipArch: string = 'C:\Temp\Test.zip';
begin
Zip.ZipFilename := ZipArch;
if Zip.ZipFilename = '' then begin
ShowMessage('¡No se pudo abrir "' + ZipArch + '"!');
exit;
end;
Zip.ExtrOptions := [ExtrTest];
try
Zip.Extract;
if Zip.ErrCode = 0 then
ShowMessage('Verificación exitosa!')
else
ShowMessage('Error(es) encontrado(s) en el archivo Zip');
except
ShowMessage('No se pudo verificar el archivo!');
end;
end;
7) Interceptando los mensajes
-----------------------------
Agregue un control Memo a su formulario y genere el evento Message del
componente Zip:
procedure TForm1.ZipMessage(Sender: TObject; ErrCode: Integer;
Message: String);
begin
if ErrCode = 0 then
Memo1.Lines.Add(Message)
else
Memo1.Lines.Add('Error Nº ' + IntToStr(ErrCode) + ': ' + Message);
end;
El Memo ahora mostrará los mensajes enviados por la DLL. Intente las
operaciones que presentamos arriba para verlos.
8) Listando los ficheros guardados en un archivo
------------------------------------------------
La propiedad ZipContents es una TList que contiene punteros a registros
ZipDirEntry que contienen información detallada acerca de los ficheros
almacenados en el archivo. Para ver un ejemplo, agregue un botón llamado
ListFiles al formulario y genere el evento Click:
procedure TForm1.ListFilesClick(Sender: TObject);
const
ZipArch: string = 'C:\Temp\Test.zip';
var
i: integer;
f: ^ZipDirEntry;
begin
Zip.ZipFilename := ZipArch;
if Zip.ZipFilename = '' then begin
ShowMessage('¡No se pudo abrir "' + ZipArch + '"!');
exit;
end;
for i := 0 to Zip.Count - 1 do begin
f := Zip.ZipContents[i];
Memo1.Lines.Add(Format('%s %.1fK (%.0f%%)', [f.FileName,
f.UncompressedSize / 1024,
f.CompressedSize / f.UncompressedSize * 100]));
end;
end;
Bueno, hasta aquí es lo más lejos que llegamos. La aplicación demo que
viene con Delphi Zip es más completa y le mostrará muchas caracterís-
ticas del componente TZipMaster (como encriptación y ejecutables
autoextractables), y puede aprender más del archivo de ayuda.
En el próximo número usaremos este componente en nuestra aplicación
Buscador de Archivos para extender la búsqueda a archivos comprimidos.
Nos vemos.
________________________________________________________________________
Si no has recibido el archivo con el código fuente completo de los
ejemplos que se presentan en este boletín, puedes descargarlo de la
siguiente dirección: http://www.latiumsoftware.com/es/file.php?id=p05
________________________________________________________________________
Página principal: http://www.latiumsoftware.com/es/pascal/index.php
Página del grupo: http://espanol.groups.yahoo.com/group/boletin-pascal/
Para suscribirse / apuntarse: boletin-pascal-subscribe@gruposyahoo.com
Para cancelar / removerse: boletin-pascal-unsubscribe@gruposyahoo.com
Para reportar problemas con la suscripción: eds2008 @ latiumsoftware.com
________________________________________________________________________
Este boletín se provee "TAL Y COMO ESTA", sin garantía de ninguna clase.
Su uso implica la aceptación de nuestros términos de licencia y de la
ausencia de garantía que puedes leer en nuestro sitio web. Allí también
encontrarás una nota sobre marcas registradas. Te animamos a que redis-
tribuyas este boletín, siempre y cuando lo hagas en forma completa
(incluyendo la información de copyright), sin modificaciones y de manera
gratuita. Los artículos son copyright de sus respectivos autores y se
reproducen aquí con el permiso de los mismos.
________________________________________________________________________
Latium Software http://www.latiumsoftware.com/es/index.php
Copyright (c) 2000 por Ernesto De Spirito. Todos los derechos reservados
________________________________________________________________________
|