Ir al contenido


Foto

Error al borrar varios archivos y/o carpetas a la vez


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

#1 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 29 diciembre 2015 - 01:39

Muy buenas noches con todos, ante todo gracias por haberme ayudado en veces pasadas, les deseo que tengan un buen año 2016 :) , ahora mi problema es el siguiente:

Resulta que deseo borrar varios archivos y/o carpetas pero de un solo tiro, es decir en un click, y lo trato de hacer de la siguiente manera:


php
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3. DeleteFileUTF8('C:\juegos\pacman.exe');
  4. DeleteFileUTF8('C:\juegos\mario.exe');
  5. DeleteFileUTF8('C:\juegos\tetris.exe');
  6. DeleteFileUTF8('C:\juegos\antman.exe');
  7. DeleteFileUTF8('C:\juegos\megaman.exe');
  8.  
  9. DeleteDirectory('C:\Program Files\fotos', false);
  10. DeleteDirectory('C:\Program Files\casa', false);
  11. DeleteDirectory('C:\Program Files\pesca', false);
  12. DeleteDirectory('C:\Program Files\huelga', false);
  13. DeleteDirectory('C:\Program Files\agua', false);
  14. DeleteDirectory('C:\Program Files\sol', false);
  15. DeleteDirectory('C:\Program Files\truchas', false);
  16. DeleteDirectory('C:\Program Files\manta', false);
  17. DeleteDirectory('C:\Program Files\arena', false);
  18. DeleteDirectory('C:\Program Files\cena', false);

Aparentemente creo que los códigos están bien, pero resulta que al momento de probarlo dando clic al "button" no me elimina todo lo que le mande, de los 15 me eliminará unos 10, o sino tengo que volver a darle clic para que acabe de eliminar el resto lo cual no entiendo porque. :( pienso que talvez el programa se marea de tantas funciones a la vez.

 

Muchas gracias por su tiempo, saludos.


  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 29 diciembre 2015 - 09:50

Yo comenzaría por verificar el resultado de cada instrucción y actuar en consecuencia.

 

Por ejemplo:


delphi
  1. begin
  2. DeleteDirectory('C:\juegos',True); //Si quieres borrar todos los archivos del directorio 'C:\juegos'
  3.  
  4. Retorno := DeleteDirectory('C:\Program Files\fotos',True); //Se borran todos los archivos
  5. if Retorno then
  6. RemoveDirUTF8('C:\Program Files\fotos')
  7. else HacemosAlgo;
  8. end;

No se mucho de Lazarus, pero me parece mas un asunto de logica que de instrucciones.
 
Saludos

  • 0

#3 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 29 diciembre 2015 - 10:37

Muchas gracias amigo egostar por su ayuda, viendo su ejemplo usted cree que también pueda probar así:


php
  1. if DeleteDirectory('C:\Program Files\fotos',True) then
  2. begin
  3. RemoveDirUTF8('C:\Program Files\fotos')
  4. else HacemosAlgo;

Por favor corrijame si estoy mal...


  • 0

#4 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 29 diciembre 2015 - 12:39

Muchas gracias amigo egostar por su ayuda, viendo su ejemplo usted cree que también pueda probar así:


php
  1. if DeleteDirectory('C:\Program Files\fotos',True) then
  2. begin
  3. RemoveDirUTF8('C:\Program Files\fotos')
  4. else HacemosAlgo;

Por favor corrijame si estoy mal...

 

 

Claro, es lo mismo y con un paso menos, de hecho yo así lo haría, pero para efectos de "comprensión" utilizo las variables de retorno. (y)

 

Saludos


  • 0

#5 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 29 diciembre 2015 - 01:46

Acabo de probarlo de esta manera amigo Egostar:


php
  1. if DeleteDirectory('C:\Program Files\fotos',True)       then RemoveDirUTF8('C:\Program Files\fotos');
  2. if DeleteDirectory('C:\Program Files\sol', True)        then RemoveDirUTF8('C:\Program Files\sol');
  3. if DeleteDirectory('C:\Program Files\casa', True)       then RemoveDirUTF8('C:\Program Files\casa');
  4. if DeleteDirectory('C:\Program Files\pesca', True)      then RemoveDirUTF8('C:\Program Files\pesca');
  5. if DeleteDirectory('C:\Program Files\huelga', True)     then RemoveDirUTF8('C:\Program Files\huelga');
  6. if DeleteDirectory('C:\Program Files\agua', True)       then RemoveDirUTF8('C:\Program Files\agua');

Y del total de 15 ahora me elimina como 13, luego lo vuelvo a ejecutar y me elimina el resto.... al menos es algo, pero sigo con la incognita a que se deberá.  :wacko:


  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 29 diciembre 2015 - 01:47

Tendría que consultar la documentación para ver cual(es) de las varias funciones que tiene disponible Lazarus son las más seguras para efectuar el borrado.

Que te borre 10 de 15 no puede ser... debería borrar todas. Lo que quizá pueda estar afectando es que alguno de esos archivos sean algo pesados y por tanto no termina de operar y/o no dejas que termine con todo.

EDITO:

Prueba a darle un poco de "respiro" entre cada borrado. El código puede mejorarse si tienes en un array o lista el nombre de los archivos y los directorios. Fíjate que todo tiene el mismo directorio raiz asi que en cada iteración puedes "armar" el path completo.

 

Saludos,


  • 0

#7 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 29 diciembre 2015 - 01:52

Acabo de probarlo de esta manera amigo Egostar:


php
  1. if DeleteDirectory('C:\Program Files\fotos',True)       then RemoveDirUTF8('C:\Program Files\fotos');
  2. if DeleteDirectory('C:\Program Files\sol', True)        then RemoveDirUTF8('C:\Program Files\sol');
  3. if DeleteDirectory('C:\Program Files\casa', True)       then RemoveDirUTF8('C:\Program Files\casa');
  4. if DeleteDirectory('C:\Program Files\pesca', True)      then RemoveDirUTF8('C:\Program Files\pesca');
  5. if DeleteDirectory('C:\Program Files\huelga', True)     then RemoveDirUTF8('C:\Program Files\huelga');
  6. if DeleteDirectory('C:\Program Files\agua', True)       then RemoveDirUTF8('C:\Program Files\agua');

Y del total de 15 ahora me elimina como 13, luego lo vuelvo a ejecutar y me elimina el resto.... al menos es algo, pero sigo con la incognita a que se deberá.  :wacko:

 

mmm, puede ser algún asunto de timer, es decir, que las instrucciones se realicen muy rápido. Si verificas que contiene cada directorio que no se borró la primera vez, contiene archivos o está vacía???? 

 

Saludos


  • 0

#8 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 29 diciembre 2015 - 02:13

Muchas gracias amigo Delphius y Egostar por su apoyo, pues en principio también pensé lo mismo, talvez mandar todas las funciones de borrado en una, puede ocasionar que no acabe bien su trabajo y el soft hace un trabajo a medias, también pienso que es algo así pues cuando lo vuelve a procesar por segunda vez entonces termina de borrar lo que falto en la primera pasada.

 

También he pensado como dice el amigo Delphius darle un respiro de esta manera:


php
  1. if DeleteDirectory('C:\Program Files\fotos',True)       then RemoveDirUTF8('C:\Program Files\fotos');
  2. sleep(3000);
  3. if DeleteDirectory('C:\Program Files\sol', True)        then RemoveDirUTF8('C:\Program Files\sol');
  4. sleep(3000);
  5. if DeleteDirectory('C:\Program Files\casa', True)       then RemoveDirUTF8('C:\Program Files\casa');
  6. sleep(3000)
  7. if DeleteDirectory('C:\Program Files\pesca', True)      then RemoveDirUTF8('C:\Program Files\pesca');

Pero no se si será la mejor manera de hacerlo.

En lo referente a lo que menciona el amigo Egostar, cuando no pudo borrar las carpetas que le pedi, estas seguían teniendo contenido, pero les repito que en la segunda pasada si los borra, esta medio raro.


  • 0

#9 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 29 diciembre 2015 - 02:28

Yo lo intentaría así:


delphi
  1. if DeleteDirectory('C:\Program Files\sol', True) then
  2. begin
  3. sleep(3000);
  4. RemoveDirUTF8('C:\Program Files\sol');
  5. end;

:)

 

Saludos 


  • 0

#10 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 29 diciembre 2015 - 02:51

Estuve leyendo la documentación y de lo que entiendo el parámetro boolean de DeleteDirectory() permite establecer si se borra todo el directorio o sólo sus archivos.

De modo que en teoría un DeleteDirectory(algo, true) borrará sólo los archivos pero dejará el directorio vacio.

Por tanto un intento de pretender borrar algo que ya ha sido borrado no tiene sentido.

Lo que no termino de entender es si hay diferencia entre un DeleteDirectory(false) y RemoveDirUTF8()

 

En teoría y hasta donde entendía la vía más segura para trabajar con los archivos son las funciones que llevan xUTF8 (en la unidad FileUtils), pero acabo de ver en el código que éstas están marcadas como predecated y simplemente se encargan de delegar el trabajo a funciones del mismo nombre hacia otra unidad (LazFileUtils). Lo chistoso es que el propio warning indica que se use las funciones de LazFileUtils. Es decir: de todas formas, al menos hasta la versión que tengo disponible, todo lleva a la unidad LazFileUtils.

Excepto DelecteDirectory(), ésta no existe en LazFileUtils.

 

Lo que me preocupa es que viendo el código de las funciones de LazFileUtils es que apunta a algo windows dependiente. Pero quizá sea que esto se debe a que en estos momentos yo tengo esto compilado en Windows y no he definido como tarjet otro SO.

 

Saludos,


  • 0

#11 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 29 diciembre 2015 - 04:10

No hay algo como RaiseLastOSError de Delphi?


  • 0

#12 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 29 diciembre 2015 - 04:17

No hay algo como RaiseLastOSError de Delphi?

 

Si lo tiene, pero en la propia doc aclara que como esto no está implementado en todos los SO, en su lugar puede arrojarse un Exception.

 

Saludos,


  • 0

#13 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 29 diciembre 2015 - 04:53

Disculpen si no fuera mucha molestía me podrían decir que es "RaiseLastOSError" y "Exception" que acaban de mencionar.


  • 0

#14 rub_n10

rub_n10

    Newbie

  • Miembros
  • Pip
  • 1 mensajes

Escrito 29 diciembre 2015 - 08:26

Podes probar dentro de un ciclo FOR repetí las veces que necesitas hasta que borre todo

Enviado desde mi C6903 mediante Tapatalk
  • 1

#15 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 30 diciembre 2015 - 03:27

Disculpen si no fuera mucha molestía me podrían decir que es "RaiseLastOSError" y "Exception" que acaban de mencionar.

 

RaiseLastOSError es una instrucción que arroja el ultimo error emitido por el SO. En teoría cuando no se puede borrar un archivo (y entre otroas cosas más) el SO responde informando en una variable de control que tipo de error se ha producido. Con RaiseLastOSError se fuerza a que se lanze un cartel de error (lo que en verdad se llama excepción) que muestre dicho error "oculto".

 

De modo que algo como:


delphi
  1. try
  2.  
  3. borrado := DeleteDirectory(...);
  4. // y otra cosa que podría dar error
  5. except
  6. RaiseLasOSError;
  7. end;

Podría justamente servir para ver que posible error se ha producido y determinar porqué no ha sido posible borrar los archivos. Pero yo tengo mis dudas de si un DeleteDirectory() o las otras funciones mencionadas en este hilo internamente puedan llevar a un estado de error y que por tanto el SO justamente guarde en la variable de control dicho error. La documentación no sugiere nada de que DeleteDirectory o alguna otra emita justamente la excepción.

 

Sugiero que más temprano que tarde te documentes sobre la clase Exception y sobre el manejo de excepciones.

 

El punto es que ya de por si estas funciones regresan un valor boolean para determinar si todo ha salido bien o no.

 

Y como he dicho, el código puede mejorarse en algo como:


delphi
  1. for i := Low(Listado) to High(Listado) do
  2. begin
  3. DeleteDirectory(Ruta + Listado[i]);
  4. wait(1000);
  5. end;

Siendo Listado algún array o también puede usarse un TStrings, en donde tienes listado todos los directorios y archivos a eliminar. Ruta es una variable en donde tienes el directorio común.

Es un esbozo, para que te hagas idea. Lo ideal sería que en lugar de un for, emplearas un ciclo while o repeat para poder ir recuperando en una variable boolean el resultado de la operación y en caso de que algo haya fallado poder terminar el ciclo sin tener que recurrir a un exit para forzarlo a interrumpirlo.

 

Saludos,


  • 0

#16 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 31 diciembre 2015 - 08:47

Los motivos por los que un archivo no puede ser borrado son los siguientes, seguro que me dejo alguno:

 

1. Error en el sistema de archivos del disco.

2. Problemas de permisos

3. Problema de atributos

4. El archivo estaba abierto (en uso), en este caso, por una app, el antivirus o el S.O. (sistema de indexación de archivos de Windows)

5. El archivo no existe.

6. Errores en la ruta.

 

Cualquier instrucción de borrado de un archivo termina en una API del S.O. que realice esa tarea, salvo errores de programación en las fuentes de la instrucción Lazarus, el archivo debería ser borrado, si no se dán las incompatibilidades antes señaladas. Puede haber un retardo en el borrado físico, pero eso no debe depender ni condicionar el código del lenguaje usado, Antes o después, el S.O. debe hacer su tarea, salvo error, que debe quedar reflejado por el mismo S.O. en LastError y debe poder ser capturado por el lenguaje en cuestión.

 

Tengo por costumbre asegurarme de que los atributos de solo lectura, oculto y de sistema, no interfieran, para ello, los cambio para asegurarme el éxito. También suelo hacerlo mediante API, pero si queremos que Lazarus no dependa de Windows, eso está vedado.

 

El error encontrado en este tema, bien pudiera ser al sistema de indexación de Windows, sobre todo en archivos largos, o del A.V. En este caso se debería capturar el error, o repetir el código hasta tener éxito. Esta segunda opción no es muy aconsejable pues se puede entrar en un bucle sin fin. Capturado el error y visto el problema que causa la denegación del borrado, se debe reintentar, si procede, o abstenerse.

 

 

Saludos.


  • 2

#17 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 31 diciembre 2015 - 11:03

Coincido plenamente con escafandra. Yo ejecutaria de la siguiente forma:


php
  1. if not DeleteDirectory(blabla) then
  2. RaiseLastOSError;
  3.  
  4. if not RemoveDirUTF8(blabla) then
  5. RaiseLastOSError;


  • 0

#18 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 31 diciembre 2015 - 11:11

Podría justamente servir para ver que posible error se ha producido y determinar porqué no ha sido posible borrar los archivos. Pero yo tengo mis dudas de si un DeleteDirectory() o las otras funciones mencionadas en este hilo internamente puedan llevar a un estado de error y que por tanto el SO justamente guarde en la variable de control dicho error. La documentación no sugiere nada de que DeleteDirectory o alguna otra emita justamente la excepción.

 

 

El punto es que ya de por si estas funciones regresan un valor boolean para determinar si todo ha salido bien o no.

 

 

 

Es muy sencillo de verificar con este codigo

 


delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3. if not DeleteFile('blabla') then
  4. RaiseLastOSError;
  5. end;
  6.  
  7. procedure TForm1.Button2Click(Sender: TObject);
  8. begin
  9. DeleteFile('blabla');
  10. end;

Ninguno de los dos botones obviamente borran ningun archivo, ya que 'blabla' no existe

Al presionar Button1 se genera una excepcion de clase EOsError informando que no se encontro el archivo especificado

Al presionar button2 no pasa nada

 

Saludos


  • 0

#19 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 259 mensajes

Escrito 31 diciembre 2015 - 07:57

Interesante amigo agustin, voy a probar "RaiseLastOSError a ver que sale...


  • 0




IP.Board spam blocked by CleanTalk.