2011-05-13 20 views
9

en mi solicitud que utilizar el siguiente procedimiento para escanear de forma recursiva cualquier carpeta y subcarpetas, si la carpeta contiene archivos de texto (* .txt) agrego el nombre del archivo a un TStringList definido en mi procedimiento:¿Cómo buscar diferentes tipos de archivos usando FindFirst?

procedure FileSearch(const PathName: string; var lstFiles: TStringList); 
const 
    FileMask = '*.txt'; 
var 
    Rec: TSearchRec; 
    Path: string; 
begin 
    Path := IncludeTrailingBackslash(PathName); 
    if FindFirst(Path + FileMask, faAnyFile - faDirectory, Rec) = 0 then 
    try 
     repeat 
     lstFiles.Add(Path + Rec.Name); 
     until FindNext(Rec) <> 0; 
    finally 
     FindClose(Rec); 
    end; 

    if FindFirst(Path + '*.*', faDirectory, Rec) = 0 then 
    try 
     repeat 
     if ((Rec.Attr and faDirectory) <> 0) and (Rec.Name <> '.') and 
      (Rec.Name <> '..') then 
      FileSearch(Path + Rec.Name, lstFiles); 
     until FindNext(Rec) <> 0; 
    finally 
     FindClose(Rec); 
    end; 
end; 

todo funciona perfecto, pero quiero poder buscar múltiples extensiones de archivo. He intentado modificar FileMask para hacerlo, pero cada vez no devuelve nada, probablemente porque está buscando una extensión no válida. He tratado de cada uno de los siguientes, pero sin suerte: (probado uno a la vez, obviamente, yo no escribí las líneas de abajo 3 veces en mi procedimiento)

FileMask = '*.txt|*.rtf|*.doc'; 

FileMask = '*.txt;*.rtf;*.doc'; 

FileMask = '*.txt,*.rtf,*.doc'; 

me siento tonta por preguntar esto, pero ¿cómo puedo permitir que las extensiones de archivo adicionales se incluyan en la búsqueda? Puedo hacerlo para los cuadros de diálogo Abrir y Guardar, ¿por qué no puedo separar las extensiones aquí?

Gracias.

Craig.

Respuesta

8

Cambie su función para que también acepte una lista de extensiones, separadas por punto y coma o algún otro delimitador. Luego puede verificar la existencia de la extensión de cada archivo encontrado en esa lista de extensiones, y si se encuentra, agréguelo a su lista de cadenas.

Algo como esto debería funcionar: Llamada

procedure FileSearch(const PathName: string; const Extensions: string; 
var lstFiles: TStringList); 
const 
    FileMask = '*.*'; 
var 
    Rec: TSearchRec; 
    Path: string; 
begin 
    Path := IncludeTrailingBackslash(PathName); 
    if FindFirst(Path + FileMask, faAnyFile - faDirectory, Rec) = 0 then 
    try 
     repeat 
     if AnsiPos(ExtractFileExt(Rec.Name), Extensions) > 0 then 
      lstFiles.Add(Path + Rec.Name); 
     until FindNext(Rec) <> 0; 
    finally 
     SysUtils.FindClose(Rec); 
    end; 

    if FindFirst(Path + '*.*', faDirectory, Rec) = 0 then 
    try 
     repeat 
     if ((Rec.Attr and faDirectory) <> 0) and (Rec.Name <> '.') and 
      (Rec.Name <> '..') then 
      FileSearch(Path + Rec.Name, Extensions, lstFiles); 
     until FindNext(Rec) <> 0; 
    finally 
     FindClose(Rec); 
    end; 
end; 

muestra:

FileSearch('C:\Temp', '.txt;.tmp;.exe;.doc', FileList); 
+0

Aceptado, perfecto gracias Ken. –

+1

PathMatchSpec en AhLwApi podría ser un poco más limpio que AnsiPos. http://msdn.microsoft.com/en-us/library/bb773727%28v=vs.85%29.aspx –

+1

@Bruce: ¿Te refieres a Shlwapi? PathMatchSpec parece comprobar solo una sola extensión a la vez, lo que significa que tendría que analizar su lista de extensiones por separado para probarla. Usar AnsiPos le permite simplemente verificar para ver si uno está en la lista delimitada. Si está preocupado por la distinción entre mayúsculas y minúsculas, podría usar 'AnsiContainsText' isntead; realiza una búsqueda insensible a mayúsculas y devuelve un booleano que indica si la subcadena existe o no. –

0

En Delphi XE7 esta línea de código genera (línea 17) un error:

finally 
    SysUtils.FindClose(Rec); 
end; 

Para corrija el error que acabo de eliminar SysUtils. para leer este código:

finally 
    FindClose(Rec); 
end; 

Ahora el código compila bien. Gracias por este código y solución tan útil.

+0

Encontré algo extraño con esta función. En término del resultado de búsqueda. Imaginemos que tengo estos archivos dentro de C: \ temp: afile.m, asong.mp3, amovie.mp4 Ahora cuando realizo una búsqueda. FileSearch ('C: \ Temp', '. *. Mp3; *. Mp4', Lista de archivos); Resultado dentro de la lista son los 3 archivos y no los 2 últimos. ¿Por qué? –

Cuestiones relacionadas