PDA

Ver la Versión Completa : ¿Cual es la mejor forma de eliminar muchos archivos?


pgranados
26-01-2023, 01:54:40
Buen día colegas, tengo una duda, ¿Cuál es la mejor (mas rápida y limpia) forma de eliminar diversos archivos?

Tengo una tabla llamada comprobantes donde almaceno el nombre del archivo, ejemplo: (Comprobante001)
Y tengo la ruta del comprobante en otra tabla llamada Parámetros, ejemplo: (C:\Programa\Comprobantes\Comprobante001.PDF)

Si tengo la tabla Comprobantes con 100 registros
Comprobante001, Comprobante002, ....... Comprobante100

¿Cuál seria la mejor forma de eliminar los 100 registros y sus respectivos archivos?

Ahorita lo que hago es un ciclo donde voy eliminando registro y archivo, pero no se porque a veces me arroja un error diciendo que el archivo no existe cuando claramente si. Anexo el código que estoy usando.



for i := 0 to FDQuery.RecordCount-1 do
begin
FDQuery.Refresh;
FormaEsperaImportacion.lbl.Refresh;
FormaEsperaImportacion.lbl.Caption:= 'Archivo Eliminado del Sistema: '+intToStr(i)+ ' de '+lsValorCount+'.';
lsNomArchXML:= FDQueryParametrosPAEXINGRESOSXML.Value+'\'+FDQuery.FieldByName('NOMBRE_ARCHIVO').Value+'.XML';
lsNomArchPDF:= FDQueryParametrosPAEXINGRESOSPDF.Value+'\'+FDQuery.FieldByName('NOMBRE_ARCHIVO').Value+'.PDF';
if DeleteFile(lsNomArchXML)then
begin
DModuloEmpresa.FDQuery.Delete;
end
else
begin showMessage('Hubo un error al eliminar el archivo XML. Favor de Eliminar Manualmente');
end;
// activar cuando los pdf se generen
if FileExists(lsNomArchPDF) then // Si existe PDF, intento eliminarlo, pregunto si existe debido a que no en todos los casos se genera el pdf
begin
if DeleteFile(lsNomArchPDF)
then
begin
// Se elimino el archivo
end else
begin showMessage('Hubo un error al eliminar el archivo PDF, Favor de Eliminar Manualmente.'); end;
end;
FDQuery.Next;
end;



Saludos

Neftali [Germán.Estévez]
26-01-2023, 09:49:48
Son dos cosas distintas, por un lado dices que a veces el procedimiento no funciona (a) y por otro lado cómo hacerlo más rápido (b).

a) En cuanto a que el procedimiento no funciona a veces, si revisas la ayuda de la función DeleteFile (https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.SysUtils.DeleteFile), verás que habla de:
"...If the file cannot be deleted or does not exist..."

Por lo tanto puede ser que el fichero exista en disco, pero no se pueda borrar por otros temas (por ejemplo, porque esté bloqueado). En ese caso no podrás borrarlo y sería el caso que tú comentas.

b) Lo segundo sería cómo hacerlo más eficiente y rápido. El código no está mal conceptualmente (en cuando a funcionamiento), se hace un recorrido y se borrar los registros y ficheros. Lo que sí es verdad es que las operaciones de disco son "lentas" en comparación con el resto.

Si necesitaras más velocidad lo siguiente podría ser utilizar Threads. En ese caso, podrías lanzar un thread para cada borrardo.
Se podría realizar el recorrido, borrar el registro y lanzar el thread para borrar los ficheros. En ese caso el programa no debería estar esperando a que acabara cada instrucción de borrado. Eso sí, tendrás que replantear la gestión de posibles errores.

duilioisola
26-01-2023, 15:55:20
Veo que borras el registro de la tabla y luego haces un Next en el bucle. Creo que así te saltarás registros de la taba.
Te recomiendo hacer una lista de los ficheros a borrar y tratarlos a todos de la misma manera (if FileExists().. if DeleteFile())
También te recomiendo utilizar while not EOF para evitar errores cuando refrescas datos en el bucle (borrar registros) y la cantidad varía.
Además de esto. Pon el nombre del fichero en el mensaje de error. Puede que veas que sale vacío o con cosas raras y te des cuenta de algún error en el algoritmo.



ListaFicheros := TStringList.Create;
try
while not FDQuery.EOF do
begin
ListaFicheros.Clear;
ListaFicheros.Add(FDQueryParametrosPAEXINGRESOSXML.Value+'\'+FDQuery.FieldByName('NOMBRE_ARCHIVO').V alue+'.XML');
ListaFicheros.Add(FDQueryParametrosPAEXINGRESOSPDF.Value+'\'+FDQuery.FieldByName('NOMBRE_ARCHIVO').V alue+'.PDF');

TodoBorrado := True;
// Recorro en forma inversa porque ire borrando los registros tratados
for i := ListaFicheros.Count -1 downto 0 do
begin
if not FileExists(ListaFicheros[i]) then
ListaFicheros.Delete(i)
else
begin
if DeleteFile(ListaFicheros[i]) then
ListaFicheros.Delete(i)
else
begin
TodoBorrado := False;
showMessage('Hubo un error al eliminar el archivo PDF' + ListaFicheros[i] + #13#10 + 'Favor de Eliminar Manualmente.');
end;
end;
end;

// Si pude borrar todos los ficheros borro el registro de la tabla
if TodoBorrado then
DModuloEmpresa.FDQuery.Delete
else
begin
// En este punto, dentro de ListaFicheros, tienes los ficheros que no se han podido borrar
FDQuery.Next;
end;
end;
finally
ListaFicheros.Free;
end;

pgranados
26-01-2023, 20:54:43
Muchas gracias por sus recomendaciones, las tendre en cuenta. Saludos.
:rolleyes: