04 septiembre 2007

Explorar unidades y directorios

Si importante es controlar el manejo de archivos no menos importante es el saber moverse por las unidades de disco y los directorios.

Veamos que tenemos Delphi para estos menesteres:

function CreateDir( const Dir: string ): Boolean;

Esta función crea un nuevo directorio en la ruta indicada por Dir. Devuelve True o False dependiendo si ha podido crearlo o no. El único inconveniente que tiene esta función es que deben existir los directorios padres. Por ejemplo:

CreateDir( 'C:\prueba' ) devuelve True
CreateDir( 'C:\prueba\documentos' ) devuelve True
CreateDir( 'C:\otraprueba\documentos' ) devuelve False (y no lo crea)

function ForceDirectories( Dir: string ): Boolean;

Esta función es similar a CreateDir salvo que también crea toda la ruta de directorios padres.

ForceDirectories( 'C:\prueba' ) devuelve True
ForceDirectories( 'C:\prueba\documentos' ) devuelve True
ForceDirectories( 'C:\otraprueba\documentos' ) devuelve True


procedure ChDir( const S: string ); overload;

Este procedimiento cambia el directorio actual al indicado por el parámetro S. Por ejemplo:

ChDir( 'C:\Windows\Fonts' );

function GetCurrentDir: string;

Nos devuelve el nombre del directorio actual donde estamos posicionados. Por ejemplo:

GetCurrentDir devuelve C:\Windows\Fonts

function SetCurrentDir( const Dir: string ): Boolean;

Establece el directorio actual devolviendo True si lo ha conseguido. Por ejemplo:

SetCurrentDir( 'C:\Windows\Java' );

procedure GetDir( D: Byte; var S: string );

Devuelve el directorio actual de una unidad y lo mete en la variable S. El parámetro D es el número de la unidad siendo:

D Unidad
--- ------------------
0 Unidad por defecto
1 A:
2 B:
3 C:
...

Por ejemplo para leer el directorio actual de la unidad C:

var
sDirectorio: String;
begin
GetDir( 3, sDirectorio );
ShowMessage( 'El directorio actual de la unidad C: es ' + sDirectorio );
end;

function RemoveDir( const Dir: string ): Boolean;

Elimina un directorio en el caso de que este vacío, devolviendo False si no ha podido hacerlo.

RemoveDir( 'C:\prueba\documentos' ) devuelve True
RemoveDir( 'C:\prueba' ) devuelve True
RemoveDir( 'C:\otraprueba' ) devuelve False porque no esta vacío

function DirectoryExists( const Directory: string ): Boolean;

Comprueba si existe el directorio indicado por el parámetro Directory. Por ejemplo:

DirectoryExists( 'C:\Windows\System32\' ) devuelve True
DirectoryExists( 'C:\Windows\MisDocumentos\' ) devuelve False

function DiskFree( Drive: Byte ): Int64;

Devuelve el número de bytes libres de una unidad de dico indicada por la letra Drive:

Drive Unidad
----------- ------
0 Unidad por defecto
1 A:
2 B:
3 C:
...

Por ejemplo vamos a ver el número de bytes libres de la unidad C:

DiskFree( 3 ) devuelve 5579714560


function DiskSize( Drive: Byte ): Int64;

Nos dice el tamaño total en bytes de una unidad de disco. Por ejemplo:

DiskSize( 3 ) devuelve 20974428160


BUSCANDO ARCHIVOS DENTRO DE UN DIRECTORIO

Para buscar archivos dentro de un directorio disponemos de las funciones:

function FindFirst( const Path: string; Attr: Integer; var F: TSearchRec ): Integer;

Busca el primer archivo, directorio o unidad que se encuentre dentro de una ruta en concreto. Devuelve un cero si ha encontrado algo. El parámetro TSearchRec es una estructura de datos donde se almacena lo encontrado:

type
TSearchRec = record
Time: Integer;
Size: Integer;
Attr: Integer;
Name: TFileName;
ExcludeAttr: Integer;
FindHandle: THandle;
FindData: TWin32FindData;
end;


function FindNext( var F: TSearchRec ): Integer;

Busca el siguiente archivo, directorio o unidad especificado anteriormente por la función FindFirst. Devuelve un cero si ha encontrado algo.

procedure FindClose( var F: TSearchRec );

Este procedimiento cierra la búsqueda comenzada por FindFirst y FindNext.

Veamos un ejemplo donde se utilizan estas funciones. Vamos a hacer un procedimiento que lista sólo los archivos de un directorio que le pasemos y vuelca su contenido en un StringList:

procedure TFPrincipal.Listar( sDirectorio: string; var Resultado: TStringList );
var
Busqueda: TSearchRec;
iResultado: Integer;
begin
// Nos aseguramos que termine en contrabarra
sDirectorio := IncludeTrailingBackslash( sDirectorio );

iResultado := FindFirst( sDirectorio + '*.*', faAnyFile, Busqueda );

while iResultado = 0 do
begin
// ¿Ha encontrado un archivo y no es un directorio?
if ( Busqueda.Attr and faArchive = faArchive ) and
( Busqueda.Attr and faDirectory <> faDirectory ) then
Resultado.Add( Busqueda.Name );

iResultado := FindNext( Busqueda );
end;

FindClose( Busqueda );
end;

Si listamos el raiz de la unidad C:

var
Directorio: TStringList;
begin
Directorio := TStringList.Create;
Listar( 'C:', Directorio );
ShowMessage( Directorio.Text );
Directorio.Free;
end;

El resultado sería:

AUTOEXEC.BAT
Bootfont.bin
CONFIG.SYS
INSTALL.LOG
IO.SYS
MSDOS.SYS
NTDETECT.COM

Con estas tres funciones se pueden hacer cosas tan importantes como eliminar directorios, realizar búsquedas de archivos, calcular lo que ocupa un directorio en bytes, etc.

Pruebas realizadas en Delphi 7.

Publicidad