Ir al contenido


Foto

Buscar Archivos en Carpetas y sub-Carpetas con filtros


  • Por favor identifícate para responder
29 respuestas en este tema

#21 rgstuamigo

rgstuamigo

    Member

  • Miembros
  • PipPip
  • 32 mensajes
  • LocationSanta Cruz-Bolivia

Escrito 07 julio 2009 - 01:57

Aunque la respuesta corta serí­a que nos gusta quemar neuronas en vano, la respuesta larga esta relacionada con recursividad; mientras que el descrito inicialmente nos retornará una lista con todos los archivos que concuerden con una lista extensiones en una ruta determinada y todas sus subcarpetas, tu solución solo retornara la ocurrencia de una mascara en una carpeta (y no así­ de las carpetas que estén dentro de ésta) ver siguiente ejemplo sin componentes;

Bueno en ese caso se puede hacer una mascara algo asi:
Mask='C:\Mi\Ruta\Completa\*.MP3;C:\Mi\Ruta\Completa\*.MP4;C:\Mi\Ruta\Completa\*.Wma' y asi detectaria todos los archivos con esas extensiones, ahora  lo unico que tienes razon es que no busca en las subcarpetas, pero creo, que con la ayuda de estos otros componentes (TDirectoryListBox, TDriveComboBox, TFilterComboBox) se puede emular lo que pretende Enecumene, en su primer post. ;)
Saludos... 8-|
  • 0

#22 Delphius

Delphius

    Advanced Member

  • Moderador
  • PipPipPip
  • 6.295 mensajes
  • LocationArgentina

Escrito 07 julio 2009 - 03:04

rgstuamigo, puede que con otros componentes se consiga lo que dices pero he aquí­ que no siempre es deseable añadir componentes. Más si no se prevee darle demasiado uso.

Te ahorras un buen espacio. Cada componente que añades va haciendo crecer más al ejecutable, añadiendo más referencias a unidades, funciones y/o procedimientos dentro de éste.

A veces es mejor tener unos métodos que disponer de unos cuantos objetos con sus otras invocaciones, etc.

Saludos,
  • 0

#23 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.259 mensajes
  • LocationMéxico

Escrito 07 julio 2009 - 03:11

Hola

Y si a eso le agregamos los problemas con componentes descontinuados o no actualizados a las nuevas versiones de Delphi, pues no quiero saber los problemas que te acarreas si quieres migrar tus aplicaciones a nuevas versiones de Delphi.

Y como dijo mi buen amigo cHackAll, no esta mal quemar algunas neuronas de vez en vez aprendiendo algo de API en lugar de buscar componentes adicionales.

Salud OS
  • 0

#24 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 07 julio 2009 - 06:34

¡Master!, ¡Usted es un genio, me arrodillo ante ti!  (y), bueno adaptondolo a mis necesidades hasta ahora ha quedado así­:



delphi
  1. unit Principal;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, StdCtrls, Grids, DBGrids, xmldom, DB, Provider, Xmlxform,
  8.   DBClient, ExtCtrls;
  9.  
  10. type
  11.   TForm1 = class(TForm)
  12.     Button1: TButton;
  13.     DBGrid1: TDBGrid;
  14.     dsCanciones: TDataSource;
  15.     cdsCanciones: TClientDataSet;
  16.     prCanciones: TXMLTransformProvider;
  17.     cdsCancionesID: TIntegerField;
  18.     cdsCancionesArtista: TStringField;
  19.     cdsCancionesTitulo: TStringField;
  20.     cdsCancionesAlbum: TStringField;
  21.     cdsCancionesGenero: TStringField;
  22.     cdsCancionesAno: TStringField;
  23.     cdsCancionesCalidad: TStringField;
  24.     cdsCancionesRuta: TStringField;
  25.     Timer1: TTimer;
  26.     Label1: TLabel;
  27.     procedure Button1Click(Sender: TObject);
  28.     procedure Timer1Timer(Sender: TObject);
  29.     procedure FormDestroy(Sender: TObject);
  30.   private
  31.     { Private declarations }
  32.     procedure Process(lpFileName: PChar);
  33.     procedure Search(const lpString: PChar); stdcall;
  34.   public
  35.     { Public declarations }
  36.   end;
  37.  
  38. var
  39.   Form1: TForm1;
  40.  
  41. implementation
  42.  
  43. uses ToFunciones;
  44.  
  45. {$R *.dfm}
  46.  
  47. function strstr(lpString, lpStrCharSet: PChar): PChar; cdecl external 'ntdll';
  48. function _strlwr(lpString: PChar): PChar; cdecl external 'ntdll';
  49.  
  50. var
  51. Path: array [0..MAX_PATH{-1}] of Char;
  52. FindFileData: TWin32FindData;
  53.  
  54. procedure TForm1.Process(lpFileName: PChar);
  55. var
  56.   Titulo,Artista,Album,Ano,Genero,Comentario,Calidad: String;
  57. begin
  58.   cdsCanciones.CreateDataSet;
  59.   ObtenerID3Tag(lpFileName,Titulo,Artista,Album,Ano,Genero,Comentario);
  60.     if cdsCanciones.Active = False then
  61.       cdsCanciones.Open;
  62.     {*** registramos en el XML ***}
  63.       cdsCanciones.Append;
  64.       cdsCanciones.FieldByName('ID').AsInteger      := cdsCanciones.RecordCount + 1;
  65.       cdsCanciones.FieldByName('Artista').AsString  := Artista;
  66.       if Titulo <> '' then
  67.       cdsCanciones.FieldByName('Titulo').AsString  := Titulo
  68.       else
  69.       cdsCanciones.FieldByName('Titulo').AsString  := lpFileName;
  70.  
  71.       cdsCanciones.FieldByName('Album').AsString    := Ano;
  72.       cdsCanciones.FieldByName('Genero').AsString  := Genero;
  73.       cdsCanciones.FieldByName('Ano').AsInteger    := StrToIntDef(Album,0);
  74.       cdsCanciones.FieldByName('Calidad').AsInteger := StrToIntDef(Calidad,0);
  75.       cdsCanciones.FieldByName('Ruta').AsString    := lpFileName;
  76.       cdsCanciones.Post;
  77. end;
  78.  
  79. procedure TForm1.Search(const lpString: PChar); stdcall;
  80. var
  81. len, hFindHandle: Cardinal;
  82. lpFileName, lpExt: PChar;
  83. begin
  84. len := lstrlen(@Path) + 1;
  85. hFindHandle := FindFirstFile(lstrcat(@Path, '\*.*'), FindFileData);
  86. if hFindHandle <> INVALID_HANDLE_VALUE then
  87.   begin
  88.   repeat lpFileName := @FindFileData.cFileName; lstrcpy(@Path[len], lpFileName);
  89.     if (FindFileData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then
  90.     if (PWord(lpFileName)^ <> Ord('.')) and (PWord(@lpFileName[1])^ <> Ord('.')) then // '.' | '..'
  91.       Search(lpString)
  92.     else
  93.     else
  94.     begin
  95.       lpExt := lpFileName;
  96.       while lpFileName[0] <> #0 do
  97.       begin
  98.         if lpFileName[0] = '.' then
  99.         lpExt := lpFileName;
  100.         Inc(lpFileName);
  101.       end;
  102.       PWord(lpFileName)^ := Ord('.');
  103.       if Assigned(strstr(lpString, _strlwr(lpExt))) then
  104.       Process(@Path); // back to VCL :( or any callback!
  105.     end;
  106.   until not FindNextFile(hFindHandle, FindFileData);
  107.   Windows.FindClose(hFindHandle);
  108.   end;
  109. end;
  110.  
  111. procedure TForm1.Button1Click(Sender: TObject);
  112. begin
  113. lstrcpy(@Path, 'c:'); // where to search
  114. Timer1.Tag := CreateThread(nil, 0{}, @Search, PChar('.mp3.wma.mp4.wav.'), 0, PDWORD(0)^); // extensions in lower case with extra point at the end!
  115. Button1.Visible := False;
  116. Timer1.Enabled := True;
  117. end;
  118.  
  119. procedure TForm1.Timer1Timer(Sender: TObject);
  120. begin
  121. if WaitForSingleObject((Sender as TComponent).Tag, 0) = WAIT_TIMEOUT then
  122.   begin
  123.   Label1.Caption := Path;
  124.   end
  125. else
  126.   begin
  127.   (Sender as TTimer).Enabled := False;
  128.   Label1.Caption := '';
  129.   Button1.Visible := True;
  130.   end;
  131. end;
  132.  
  133. procedure TForm1.FormDestroy(Sender: TObject);
  134. begin
  135. if Timer1.Enabled then
  136.   TerminateThread(Timer1.Tag, 0);
  137. end;
  138.  
  139. end.



Pero al compilar me da problemas en la lí­nea:



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3. lstrcpy(@Path, 'c:'); // where to search
  4. Timer1.Tag := CreateThread(nil, 0{}, @Search, PChar('.mp3.wma.mp4.wav.'), 0, PDWORD(0)^); // Aquí­ se detiene
  5. Button1.Visible := False;
  6. Timer1.Enabled := True;
  7. end;



Este es el error:



delphi
  1. [Error] Principal.pas(114): Variable required



Y se posiciona en el puntero @Search, ¿qué hago mal? :(.

Saludos.
  • 0

#25 cHackAll

cHackAll

    Advanced Member

  • Moderador
  • PipPipPip
  • 598 mensajes

Escrito 08 julio 2009 - 08:15



delphi
  1. // . . .
  2.  
  3.   private
  4.   {}
  5.   public
  6.   end;
  7.  
  8. var
  9.   Form1: TForm1;
  10.  
  11. implementation
  12.  
  13. uses ToFunciones;
  14.  
  15. {$R *.dfm}
  16.  
  17. function strstr(lpString, lpStrCharSet: PChar): PChar; cdecl external 'ntdll';
  18. function _strlwr(lpString: PChar): PChar; cdecl external 'ntdll';
  19.  
  20. var
  21. Path: array [0..MAX_PATH{-1}] of Char;
  22. FindFileData: TWin32FindData;
  23.  
  24. procedure Process(lpFileName: PChar);
  25. var Titulo,Artista,Album,Ano,Genero,Comentario,Calidad: String;
  26. begin
  27. with Form1 do
  28.   begin
  29.   cdsCanciones.CreateDataSet;
  30.   ObtenerID3Tag(lpFileName,Titulo,Artista,Album,Ano,Genero,Comentario);
  31.   if cdsCanciones.Active = False then
  32.     cdsCanciones.Open;
  33.     {*** registramos en el XML ***}
  34.   cdsCanciones.Append;
  35.   cdsCanciones.FieldByName('ID').AsInteger      := cdsCanciones.RecordCount + 1;
  36.   cdsCanciones.FieldByName('Artista').AsString  := Artista;
  37.   if Titulo <> '' then
  38.     cdsCanciones.FieldByName('Titulo').AsString  := Titulo
  39.   else
  40.     cdsCanciones.FieldByName('Titulo').AsString  := lpFileName;
  41.  
  42.   cdsCanciones.FieldByName('Album').AsString    := Ano;
  43.   cdsCanciones.FieldByName('Genero').AsString  := Genero;
  44.   cdsCanciones.FieldByName('Ano').AsInteger    := StrToIntDef(Album,0);
  45.   cdsCanciones.FieldByName('Calidad').AsInteger := StrToIntDef(Calidad,0);
  46.   cdsCanciones.FieldByName('Ruta').AsString    := lpFileName;
  47.   cdsCanciones.Post;
  48.   end;
  49. end;
  50.  
  51. procedure Search(const lpString: PChar); stdcall;
  52. var
  53. len, hFindHandle: Cardinal;
  54. lpFileName, lpExt: PChar;
  55. begin
  56. len := lstrlen(@Path) + 1;
  57. hFindHandle := FindFirstFile(lstrcat(@Path, '\*.*'), FindFileData);
  58. if hFindHandle <> INVALID_HANDLE_VALUE then
  59.   begin
  60.   repeat lpFileName := @FindFileData.cFileName; lstrcpy(@Path[len], lpFileName);
  61.     if (FindFileData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then
  62.     if (PWord(lpFileName)^ <> Ord('.')) and (PWord(@lpFileName[1])^ <> Ord('.')) then // '.' | '..'
  63.       Search(lpString)
  64.     else
  65.     else
  66.     begin
  67.       lpExt := lpFileName;
  68.       while lpFileName[0] <> #0 do
  69.       begin
  70.         if lpFileName[0] = '.' then
  71.         lpExt := lpFileName;
  72.         Inc(lpFileName);
  73.       end;
  74.       PWord(lpFileName)^ := Ord('.');
  75.       if Assigned(strstr(lpString, _strlwr(lpExt))) then
  76.       Process(@Path); // back to VCL :( or any callback!
  77.     end;
  78.   until not FindNextFile(hFindHandle, FindFileData);
  79.   Windows.FindClose(hFindHandle);
  80.   end;
  81. end;
  82.  
  83. procedure TForm1.Button1Click(Sender: TObject);
  84. begin
  85. lstrcpy(@Path, 'c:'); // where to search
  86. Timer1.Tag := CreateThread(nil, 0{}, @Search, PChar('.mp3.wma.mp4.wav.'), 0, PDWORD(0)^); // extensions in lower case with extra point at the end!
  87. Button1.Visible := False;
  88. Timer1.Enabled := True;
  89. end;
  90.  
  91. // . . .


  • 0

#26 rgstuamigo

rgstuamigo

    Member

  • Miembros
  • PipPip
  • 32 mensajes
  • LocationSanta Cruz-Bolivia

Escrito 08 julio 2009 - 01:15

rgstuamigo, puede que con otros componentes se consiga lo que dices pero he aquí­ que no siempre es deseable añadir componentes. Más si no se prevee darle demasiado uso.

Te ahorras un buen espacio. Cada componente que añades va haciendo crecer más al ejecutable, añadiendo más referencias a unidades, funciones y/o procedimientos dentro de éste.

A veces es mejor tener unos métodos que disponer de unos cuantos objetos con sus otras invocaciones, etc.

Saludos,

Bueno... creo que eso ya depende de cada uno, *-)aunque tambien se podria crear los componentes dinamicamente(en Tiempo de ejecucion) y luego eliminarlo(Liberarlos),y ademas no creo que una aplicasion como la que pretende Enecumene pese tanto como para andar pensando en el tamaño del ejecutable,como ejemplo te pongo que yo tengo un ejecutable de casi 10 mega ,como 70 formularios y me funciona muy bien (y);pero como ya dije eso depende de cada uno..... :wink:
  • 0

#27 Delphius

Delphius

    Advanced Member

  • Moderador
  • PipPipPip
  • 6.295 mensajes
  • LocationArgentina

Escrito 08 julio 2009 - 08:13

Pues si rgstuamigo, eso es a gustos de cada uno y de un gran y relativo DEPENDE. :wink:

Saludos,
  • 0

#28 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 20 julio 2009 - 07:39

ChackAll, ese último code está excelente amigo y disculpa la tardanza, fí­jate, perdona si molesto bastante, de veras traté de entender un poco tu code para poder modificarlo y pues no tengo las mismas neuronas que tú, querí­a que así­ como es multi-máscara también fuera multi-path, algo como así­:



delphi
  1. lstrcpy(@Path, PChar('.C:\.D:\.E:\.')); // where to search



No sé si es factible, intenté hacerlo en un ciclo for como verás en este hilo que abrí­, pero nada, no nos sale :(.

Saludos.
  • 0

#29 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 24 julio 2009 - 07:56

Estuve pensando si se puede guardar el resultado del conteo en un array y colocarlo en la función lstrcpy, no sé, ¿se podrá?. *-)
  • 0

#30 cannabis

cannabis

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 257 mensajes
  • LocationMéxico

Escrito 19 noviembre 2009 - 01:01

En delphiarea.com hay un componente gratuito FindFile que es una pasada..
Trabaja con filtros de todo tipo y se puede utilizar en multitarea...


Gracias por el dato alquimista. Me estaba quemando las pestañas tratando de inventar el hilo negro y el agua tibia.


Salud.

  • 0