31 agosto 2007

Trabajando con archivos de texto y binarios (IV)

En el artículo anterior vimos como movernos por un archivo binario utilizando la propiedad Position de la clase TFileStream. Ahora vamos a ver lo mismo utilizando AssignFile.

RECORRIENDO UN ARCHIVO BINARIO EN MODO LECTURA

Si utilizamos AssignFile para leer un archivo en vez de TFileStream podemos mover el puntero en cualquier dirección utilizando el procedimiento Seek:

procedure Seek( var F; N: Longint );

Este procedimiento toma como primer parámetro el puntero al archivo (F: File of Byte) y como segundo parámetro la posición donde queremos movernos, siendo cero la primera posición. Para irse al final del archivo se hace:

Seek( F, FileSize(F) )

Vamos a abrir el archivo prueba.dat de 100 KB creado anteriormente y nos vamos a ir a la posición 50 para leer 10 bytes volcando la información en un campo memo en formato hexadecimal:

var F: file of byte;
i: Integer;
Buffer: array[0..9] of Byte;
begin
AssignFile( F, ExtractFilePath( Application.ExeName ) + 'prueba.dat' );
Reset( F );
Seek( F, 50 );
BlockRead( F, Buffer, 10 );

for i := 0 to 9 do
Memo.Text := Memo.Text + IntToHex( Buffer[i], 2 ) + ' ';

CloseFile( F );
end;

El resultado sería:

32 33 34 35 36 37 38 39 3A 3B

El único inconveniente que tiene la función Seek es que sólo funciona en modo lectura (Reset). No se puede utilizar en modo escritura (Rewrite) para irse al final del archivo y seguir añadiendo datos.

Si no sabemos donde estamos se puede utilizar la función FilePos para averiguarlo:

ShowMessage( 'posición: ' + IntToStr( FilePos( F ) ) );


LEYENDO LAS PROPIEDADES DE UN ARCHIVO

Veamos de que funciones dispone Delphi para leer los atributos de un archivo (fecha, modo de acceso. etc.):

function FileAge( const FileName: string ): Integer;

Esta función devuelve la fecha y hora de última modificación de un archivo en formato TTimeStamp. Para pasar de formato TTimeStamp a formato TDateTime utilizamos la función FileDateToDateTime. Por ejemplo:

FileDateToDateTime( FileAge( 'prueba.txt' ) ) -> devuelve la fecha y hora de modificación del archivo prueba.txt

También disponemos de una función para obtener los atributos de un archivo:

function FileGetAttr( const FileName: string ): Integer;

Devuelve un valor entero conteniendo los posibles atributos de un archivo (puede tener varios a la vez). Por ejemplo, para averiguar si el archivo esta oculto se haría lo siguiente:

var
iAtributos: Integer;
begin
if ( iAtributos and faHidden <> 0 ) and ( iAtributos and faArchive <> 0 ) then
...
end;

Esta función no sólo comprueba archivos, sino también directorios y unidades de disco. Todos los posibles valores se encuentran en binario activando el bit correspondiente. Los valores posibles son:

Constante Valor Tipo de archivo
-------------------------------------------------------------------------------------------
faReadOnly 1 Sólo lectura
faHidden 2 Oculto
faSysFile 4 Archivo del sistema
faVolumeID 8 Unidad de disco
faDirectory 16 Directorio
faArchive 32 Archivo
faSymLink 64 Enlace simbólico
faAnyFile 71 Cualquier archivo

Otra función interesante es FileSize la cual devuelve en bytes el tamaño de un archivo. El único inconveniente es que hay que abrir el archivo para averiguarlo:

var
F: File of byte;
begin
AssignFile( F, 'c:\prueba.txt' );
Reset( F );
ShowMessage( IntToStr( FileSize( F ) ) + ' bytes' );
CloseFile( F );
end;


MODIFICANDO LAS PROPIEDADES DE UN ARCHIVO

Las función para modificar las propiedad de un archivo es:

function FileSetAttr( const FileName: string; Attr: Integer ): Integer;

Si se pudo modificar el atributo del archivo devuelve un 0 o en caso de error el código del mismo. Por ejemplo para hacer un archivo de sólo lectura y oculto:

FileSetAttr( 'c:\prueba.txt', faReadOnly or faHidden );

En el próximo artículo terminaremos de ver las funciones más importates para el manejo de archivos.

Pruebas realizadas en Delphi 7.

Publicidad