PDA

Ver la Versión Completa : FindFirst, FindNext, FindClose


DJ VMan
15-11-2003, 13:38:47
Hola.

Quiero hacer una pequeña utilidad para mis mp3. Para ello hice una procedure, la cual a partir de la ruta entregada, me devuelve todos los archivos contenidos en esa carpeta (al menos esa es la idea).

El problema es que supuestamente lo hace bien, pero cuando quiero ver cuantos mp3 contó me arroja un valor menor al real. Me explico.

Le doy la ruta de mis mp3 ("E:\mp3") en la cual tengo 4.591 mp3 (valor real, lo saque por el SO y por winamp y me da ese valor), pero al correr el programa me arroja 4.467 mp3.

Quisiera saber cual es el problema y si alguien puede correr el codigo para ver donde me equivoco. Aqui está el código:

procedimiento recursivo:
-----------------------------
procedure TForm1.BuscaArchivos(Ruta,Mask:String;Atributos:Integer);
var
sr :TSearchRec;
FileAttrs : integer;
begin
FileAttrs := Atributos;
if FindFirst(Ruta+Mask, FileAttrs, sr) = 0 then begin
repeat
if ((sr.Attr and FileAttrs) = sr.Attr) and (sr.Name <> '.') and (sr.Name <> '..') then begin
if sr.Attr = faDirectory then
BuscaArchivos(Ruta + '\' + sr.Name,Mask,FileAttrs)
else begin
ListBox1.Items.Add(Ruta + '\' + sr.Name);
ListBox1.Update;
end;
end;
until FindNext(sr) <> 0;
FindClose(sr);
end;
end;

LLAMADA AL PROCEDIMIENTO RECURSIVO:
BuscaArchivos(Ruta,'\*.*',faAnyFile);
en donde ruta, en mi caso, es "E:\mp3"

La cantidad de archivos contados debiese estar en:
ListBox1.Items.Count;

nota: deduci este procedimiento de la ayuda en delphi sobre FindFirst, FindNext y FindClose.

desde ya gracias

roman
16-11-2003, 04:57:17
Hay dos problemas en tu código.

El primero es fácil detectar; está en la línea donde detectas si es o no un directorio:

if sr.Attr = faDirectory then

Debería ser:

if (sr.Attr and faDirectory) = faDirectory then

El segundo problema no estoy muy seguro a qué se debe aunque sé como evitarlo. Me parece que hay algo mal con la implementación que hace Delphi en cuanto a los atributos de archivos; creo que no incluye todos de manera que hay archivos que se pierden en la línea:

if ((sr.Attr and FileAttrs) = sr.Attr) and (sr.Name <> '.') and (sr.Name <> '..') then

por la primera condición. Pareciera que faAnyFile realmente no incluye a todos los posibles atributos.

Si quitas esa condición:

((sr.Attr and FileAttrs) = sr.Attr)

todo trabaja bien. Lo digo porque a mi me ocasionó los mismos problemas que a tí aún corrigiendo el primer problema.

Habrá que investigarle más. En el caso explícito que mencionas no hay diferencia ya que de cualquier forma estás buscando todo tipo de archivos por lo que la condición no afecta.

// Saludos

DJ VMan
17-11-2003, 00:09:53
Pues gracias roman.

Por tus comentarios, pude darme cuenta de dos cosas:

1.- verdaderamente hay algo para en delphi (o el SO o algo) que no incluye todos los archivos. ¿Como me di cuenta? Me di la laboriosa tarea de ver archivo por archivo y me di cuenta que algunas carpetas y archivos no tenian ninguna propiedad marcada (en propiedades). Luego hice un ShowMessage de las propiedades que detectaba delphi (ShowMessage(IntToStr(sr.Attr))) y me arrojaba 128, numero que no consigo obtener incluso si sumo todos los valores que aparecen en SysUtils.

2.- Como no lograba obtener el verdadero valor de cada archivo, y como necesitaba sólo los mp3. Modifique el codigo para que identificara sólo a los mp3, y, cualquier cosa que no fuera mp3, siguiera la recursividad.

es asi que llegue a:

...
repeat
if (sr.Name <> '.') and (sr.Name <> '..') then begin
if LowerCase(ExtractFileExt(sr.name)) <> '.mp3' then
BuscaArchivos(Ruta + '\' + sr.Name,Mask,FileAttrs)
else if LowerCase(ExtractFileExt(sr.name)) = '.mp3' then begin
ListBox1.Items.Add(Ruta + '\' + sr.Name);
ListBox1.Update;
end;
end;
...

Bueno, como experiencia y como tu bien dices, "abrá que investigarle más".

Muchas gracias...

jachguate
17-11-2003, 00:47:20
yo te recomiendo mantener una condición que verifique si es un directorio para la recursividad, por cuestiones de eficiencia de tu programa.

Como ya comentaron, habrá que investigar un poco mas, pero sigue siendo válido hacer:


if [sr.Attr and faDirectory] faDirectory then
BuscaArchivos(Ruta + '\' + sr.Name,Mask,FileAttrs)


o también has tenido problemas con esto??

Hasta luego

;)

DJ VMan
17-11-2003, 01:36:53
jachguate:

No he tenido problemas con esa linea, y seguiré el consejo de uds. y lo haré asi, pero con el codigo que postié antes, tambien funciona.

En cuanto al rendimiento, no he visto una gran mejora (tengo 4.591 temas, no se si con mas se notaria).