No borrar una carpeta si contiene archivos no cerrados - página 6

 
Me preguntaba de qué se trataba. Cuando esté libre, lo investigaré... Por supuesto, me gustaría una declaración más concisa de la tarea
 
Vladimir Karputov:

Por favor, continúe, siempre que escriba en el fascinante género de la "ficción". Con suerte, hacia la página 40 habrás pasado a la literatura técnica.

El error está implícito. Es difícil dar más detalles técnicos en este momento.
 
Реter Konow:

Tengo todos los archivos borrados incluso sin cerrarlos explícitamente. Borrados porque no los creé y estaban previamente dentro de la carpeta Archivos.

La cuestión es que para borrar un archivo, necesitamos su mango. Sin embargo, si no creamos este archivo, sino que sólo lo colocamos en la carpeta Files, no podemos obtener su handle, y por lo tanto no podemos cerrarlo con FileClose().

Al mismo tiempo, podemos copiarlo o borrarlo. Sin embargo, la carpeta no puede ser eliminada después de eso ni programada ni manualmente. Manualmente sólo después de reiniciar el terminal.

Más adelante intentaré reproducir el problema de forma más clara, con ejemplos ilustrativos.

El código sólo tiene que estar completo. Si el archivo está abierto, debe cerrarse antes de apagar el ordenador o cerrar MT4/5. Y preferiblemente, el asa debe ser accesible desde cualquier lugar del programa. Esto es IMHO. Mejor aún, cierre el archivo inmediatamente después de realizar una operación de lectura/escritura con él o incluso si no tiene que hacer nada con él.

La documentación de ejemplo parece mostrar cómo no hacerlo.

También es muy importante recordar que cuando se escribe en un archivo, el archivo escrito sólo se puede leer si se vacían todos los datos que quedan en el búfer de E/S del archivo en el disco utilizando FileFlush o cerrando el archivo. El cierre del archivo forzará un reinicio de los datos en el disco.

Resumen: Si abres un archivo, no olvides cerrarlo. Y no se perderá el mango del archivo.

Документация по MQL5: Файловые операции / FileFlush
Документация по MQL5: Файловые операции / FileFlush
  • www.mql5.com
Файловые операции / FileFlush - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Alexey Viktorov:

El código simplemente tiene que estar completo. Si un archivo está abierto, debe cerrarse antes de apagar el ordenador o cerrar MT4/5. Y el mango, preferiblemente, debe ser accesible desde cualquier lugar del programa. Esto es IMHO. Mejor aún, cierre el archivo inmediatamente después de la operación de lectura/escritura con él o incluso si no tuvo que hacer nada con él.

La documentación de ejemplo parece mostrar cómo no hacerlo.

También es muy importante recordar que cuando se escribe en un archivo, el archivo escrito sólo se puede leer si se vacían todos los datos que quedan en el búfer de E/S del archivo en el disco utilizando FileFlush o cerrando el archivo. El cierre del archivo forzará un reinicio de los datos en el disco.

Resumen: Si abres un archivo, no olvides cerrarlo. Y no se perderá el mango del archivo.

Una vez más, puedo cerrar un archivo creado por mi programa usando la función FileClose() - tengo su mango.

No puedo cerrar un archivo creado por otra persona, pero que existe en la carpeta Archivos, porque no tengo un controlador para él.

Si copio un archivo, que no fue creado por mí (no por mi programa), entonces no puedo cerrarlo después de copiarlo con la función FileClose() (no hay manija), PERO puedo borrarlo.

Tal vez por eso las carpetas con archivos copiados y borrados no son eliminadas por la función FolderClean(). Probablemente, porque no se cerraron después de ser copiados.

PERO NO SE PUEDEN CERRAR PORQUE NO TIENEN ASA.

:)))

 

Preguntas para los desarrolladores:

1. ¿Cómo puedo obtener el control del archivo que se creó en la carpeta Files antes de cargar el script?

2. ¿Podría tener la causa anterior el problema de borrar carpetas mediante FolderClean(), después de borrar los archivos que hay en ellas y que se copiaron previamente a otra carpeta y no se cerraron tras la copia (porque no hay asa)?

 
Реter Konow:

Preguntas para los desarrolladores:

1. ¿Cómo puedo obtener el control del archivo que se creó en la carpeta Files antes de cargar el script?

2. ¿Podría el problema de borrar carpetas con la función FolderClean(), después de borrar archivos en ellas que fueron copiados previamente en otra carpeta y que no se cerraron después de la copia (porque no hay un manejador), tener la razón anterior?


Esto es más o menos lo básico del sistema operativo. Si una aplicación ha abierto un archivo para escribirlo, ni ese archivo ni la carpeta que lo contiene pueden ser eliminados. Intenta abrir un archivo en Word y luego utilizar las herramientas del sistema operativo para eliminar la carpeta en la que se encuentra. ¿Qué pasará? No podrás, porque no tendrás acceso a ella.

Bueno, puedes conseguir el mango del archivo. Pero, ¿de qué serviría esa acción? Después de todo, si el archivo es abierto por otra aplicación, verá la declaración anterior. Sólo obtendremos un manejador que sea válido en nuestra aplicación.

 
Ihor Herasko:

Esto es más o menos lo básico del sistema operativo. Si una aplicación ha abierto un archivo para escribirlo, no se puede eliminar ni el archivo ni la carpeta que lo contiene. Intenta abrir un archivo en Word y luego usar el sistema operativo para eliminar la carpeta en la que se encuentra. ¿Qué pasará? No podrás, porque no tendrás acceso a ella.

Bueno, puedes conseguir el mango del archivo. Pero, ¿de qué serviría esa acción? Después de todo, si el archivo es abierto por otra aplicación, verá la declaración anterior. Y sólo podemos obtener un mango que sea válido en nuestra aplicación particular.

El archivo es abierto por mi aplicación (navegador de archivos) para ser sobrescrito en otra carpeta.

Después de sobrescribir necesito cerrar el archivo pero no puedo - (no hay asa) así que simplemente borro el archivo.

No hay ningún asidero porque el archivo fue creado no se sabe cuándo y no se sabe por quién.

Al mismo tiempo, el archivo existe dentro de la carpeta Files y puede ser copiado a otra carpeta y luego borrado.

Pero después de copiar, el archivo no puede cerrarse. No hay asa.

Esta es probablemente la razón por la que el borrado posterior de carpetas FolderClean() con archivos borrados, no funciona.


Pregunta: ¿Cómo puedo introducir el mango de este archivo en el programa MQL?

 

Este parece ser un problema al que todavía no se ha enfrentado la comunidad... :)

Vale, ya se me ocurrirá algo.

Siempre lo hago).

 

Desmontando mitos.

Por lo tanto, los datos del terminal en el sistema operativo:

2017.08.28 22:20:53.474 Terminal        MetaTrader 5 x64 build 1653 started (MetaQuotes Software Corp.)
2017.08.28 22:20:53.476 Terminal        Windows 10 Pro (x64 based PC), IE 11.00, UAC, Intel Core i3-3120 M  @ 2.50 GHz, RAM: 4830 / 8077 Mb, HDD: 315702 / 475588 Mb, GMT+02:00
2017.08.28 22:20:53.476 Terminal        C:\Users\barab\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075

En el momento de las pruebas, se ha creado la carpeta "test" en [carpeta de datos]\MQL5\Files y se ha creado en ella el archivo de texto "source.txt" con el siguiente contenido:

FileCopy
The function copies the original file from a local or shared folder to another file.
bool  FileCopy( 
   const string  src_file_name,     // Name of a source file 
   int           common_flag,       // Location 
   const string  dst_file_name,     // Name of the destination file 
   int           mode_flags         // Access mode 
   );


Entonces, paso 1: Copiar el archivo "source.txt" en otro utilizando las herramientas MQL5

Guión:

//--- display the window of input parameters when launching the script 
#property script_show_inputs 
//--- input parameters 
input string InpSrc="test\\source.txt";       // source 
input string InpDst="test\\destination.txt";  // copy 
input int    InpEncodingType=FILE_ANSI; // ANSI=32 or UNICODE=64 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart()
  {
//--- display the source contents (it must exist) 
   if(!FileDisplay(InpSrc))
      return;
//--- check if the copy file already exists (may not be created) 
   if(!FileDisplay(InpDst))
     {
      //--- the copy file does not exist, copying without FILE_REWRITE flag (correct copying) 
      if(FileCopy(InpSrc,0,InpDst,0))
         Print("File is copied!");
      else
         Print("File is not copied!");
     }
   else
     {
      //--- the copy file already exists, try to copy without FILE_REWRITE flag (incorrect copying) 
      if(FileCopy(InpSrc,0,InpDst,0))
         Print("File is copied!");
      else
         Print("File is not copied!");
      //--- InpDst file's contents remains the same 
      FileDisplay(InpDst);
      //--- copy once more with FILE_REWRITE flag (correct copying if the file exists) 
      if(FileCopy(InpSrc,0,InpDst,FILE_REWRITE))
         Print("File is copied!");
      else
         Print("File is not copied!");
     }
//--- receive InpSrc file copy 
   FileDisplay(InpDst);
  }
//+------------------------------------------------------------------+ 
//| Read the file contents                                           | 
//+------------------------------------------------------------------+ 
bool FileDisplay(const string file_name)
  {
//--- reset the error value 
   ResetLastError();
//--- open the file 
   int file_handle=FileOpen(file_name,FILE_READ|FILE_WRITE|FILE_TXT|InpEncodingType);
   if(file_handle!=INVALID_HANDLE)
     {
      //--- display the file contents in the loop 
      Print("+---------------------+");
      PrintFormat("File name = %s",file_name);
      while(!FileIsEnding(file_handle))
         Print(FileReadString(file_handle));
      Print("+---------------------+");
      //--- close the file 
      FileClose(file_handle);
      return(true);
     }
//--- failed to open the file 
   PrintFormat("%s is not opened, error = %d",file_name,GetLastError());
   return(false);
  }
//+------------------------------------------------------------------+


Paso 2: Limpieza de la carpeta "test" con las herramientas MQL5

Guión:

//+------------------------------------------------------------------+
//|                                                  FolderClean.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- Description 
#property description "The script shows a sample use of FolderClean()." 
//--- Show the dialog of input parameters when starting the script 
#property script_show_inputs 
//--- Input parameters 
input string   foldername="test";  // folder in MQL5/Files/ 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart()
  {
//--- Start to delete files 
   PrintFormat("Trying to delete all files from folder %s",foldername);
   if(FolderClean(foldername,0))
      PrintFormat("Files have been successfully deleted, %d files left in folder %s",
                  foldername,
                  FilesInFolder(foldername+"\\*.*",0));
   else
      PrintFormat("Failed to delete files from folder %s. Error code %d",foldername,GetLastError());
//--- 
  }
//+------------------------------------------------------------------+ 
//| Returns the number of files in the specified folder              | 
//+------------------------------------------------------------------+ 
int FilesInFolder(string path,int flag)
  {
   int count=0;
   long handle;
   string filename;
//--- 
   handle=FileFindFirst(path,filename,flag);
//--- If at least one file found, search for more files 
   if(handle!=INVALID_HANDLE)
     {
      //--- Show the name of the file 
      PrintFormat("File %s found",filename);
      //--- Increase the counter of found files/folders 
      count++;
      //--- Start search in all files/folders  
      while(FileFindNext(handle,filename))
        {
         PrintFormat("File %s found",filename);
         count++;
        }
      //--- Do not forget to close the search handle upon completion 
      FileFindClose(handle);
     }
   else // Failed to get the handle 
     {
      PrintFormat("Files search in folder %s failed",path);
     }
//--- Return the result 
   return count;
  }
//+------------------------------------------------------------------+


Paso 3: Eliminación de la carpeta "test" mediante las herramientas MQL5

//+------------------------------------------------------------------+
//|                                                 FolderDelete.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- Description 
#property description "The script shows a sample use of FolderDelete()." 
#property description "First two folders are created; one of them is empty, the second one contains a file." 
#property description "When trying to delete a non-empty folder, an error is returned and a warning is shown."

//--- Show the dialog of input parameters when starting the script 
#property script_show_inputs 
//--- Input parameters 
input string   InpFolder="test";     // An empty folder 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart()
  {
//--- Delete the comment form the chart 
   Comment("");
//--- Add a message into the "Experts" journal 
   PrintFormat("Trying to delete folder %s",InpFolder);
   ResetLastError();
//--- Delete the empty folder 
   if(FolderDelete(InpFolder))
      //--- The following message should appear since the folder is empty 
      PrintFormat("Folder %s has been successfully deleted",InpFolder);
   else
      PrintFormat("Failed to delete folder %s. Error code=%d",InpFolder,GetLastError());
//--- 
  }
//+------------------------------------------------------------------+


¿Cuál es el problema? Todo funciona.

Archivos adjuntos:
 
Vladimir Karputov:

¿Cuál es el problema? Todo funciona.

Gracias por el ejemplo. Lo resolveré mañana por la mañana. Ahora mismo no tengo energía).

Probaré todo y te daré una respuesta.


Añadido:

Has citado tres guiones diferentes aquí.

Tengo un programa y copiar, borrar archivos y carpetas sucede dentro de una función en dos ciclos.

Entra en el primer ciclo: primero se copian los archivos de origen en otra carpeta y luego se borran esos archivos de origen. Salir del primer ciclo.

Entramos en el segundo bucle: limpiamos la carpeta de origen con FolderClean() y borramos la carpeta de origen con -FolderDelete().


Entonces miramos en el navegador de archivos del meta-editor y vemos que la carpeta de origen ha sido parcialmente borrada. Las subcarpetas que no tenían archivos se han borrado completamente y las que tenían algunos archivos no se han borrado, pero están vacías.

Tratando de eliminar las carpetas manualmente - lo tenemos:



A continuación, cerramos el terminal y lo iniciamos de nuevo. Vemos que algunas subcarpetas desaparecieron por sí solas, otras permanecieron. Los borramos manualmente sin problemas. Esta vez.