Un dossier n'est pas supprimé s'il contient des fichiers non fermés. - page 6

 
Je me suis demandé de quoi il s'agissait. Quand je serai libre, j'y jetterai un coup d'oeil... Bien sûr, j'aimerais un énoncé plus concis de la tâche.
 
Vladimir Karputov:

Continuez, tant que vous écrivez dans le genre fascinant de la "fiction". Avec un peu de chance, à la page 40, vous serez passé à la littérature technique.

L'erreur est implicite. Il est difficile de donner plus de détails techniques pour le moment.
 
Реter Konow:

J'ai effacé tous les fichiers, même sans les fermer explicitement. Effacés parce que je ne les ai pas créés et qu'ils étaient auparavant dans le dossier Files.

Le fait est que pour effacer un fichier, nous avons besoin de son identifiant. Cependant, si nous n'avons pas créé ce fichier, mais l'avons seulement placé dans le dossier Files, nous ne pouvons pas obtenir son handle, et donc nous ne pouvons pas le fermer avec FileClose().

En même temps, nous pouvons toujours le copier ou l'effacer. Cependant, le dossier ne peut plus être supprimé après cela, que ce soit par programme ou manuellement. Manuellement, seulement après avoir redémarré le terminal.

J'essaierai plus tard de reproduire le problème plus clairement, avec des exemples illustratifs.

Il suffit que le code soit complet. Si le fichier est ouvert, il doit être fermé avant l'arrêt de l'ordinateur ou la fermeture de MT4/5. Et de préférence, la poignée doit être accessible de n'importe quel endroit du programme. C'est IMHO. Mieux encore, fermez le fichier immédiatement après avoir effectué une opération de lecture/écriture avec lui ou même si vous n'avez rien à faire avec lui.

L'exemple de documentation semble montrer comment ne pas le faire.

Il est également très important de se rappeler que lorsqu'on écrit dans un fichier, le fichier écrit ne peut être lu qu'en vidant sur le disque toutes les données restantes dans le tampon d'E/S du fichier à l'aide de FileFlush ou en fermant le fichier. La fermeture du fichier forcera une réinitialisation des données sur le disque.

Résumé : Si vous ouvrez un fichier, n'oubliez pas de le fermer. Et l'identifiant du fichier ne sera pas perdu.

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

Il suffit que le code soit complet. Si un fichier est ouvert, il doit être fermé avant d'éteindre l'ordinateur ou de fermer MT4/5. Et la poignée, de préférence, doit être accessible de n'importe quel endroit du programme. C'est mon opinion. Mieux encore, fermez le fichier immédiatement après avoir effectué une opération de lecture/écriture avec lui ou même si vous n'avez rien à faire avec lui.

L'exemple de documentation semble montrer comment ne pas le faire.

Il est également très important de se rappeler que lorsqu'on écrit dans un fichier, le fichier écrit ne peut être lu qu'en vidant sur le disque toutes les données restantes dans le tampon d'E/S du fichier à l'aide de FileFlush ou en fermant le fichier. La fermeture du fichier forcera une réinitialisation des données sur le disque.

Résumé : Si vous ouvrez un fichier, n'oubliez pas de le fermer. Et l'identifiant du fichier ne sera pas perdu.

Encore une fois, je peux fermer un fichier créé par mon programme en utilisant la fonction FileClose() - j'ai son identifiant.

Je ne peux pas fermer un fichier créé par quelqu'un d'autre, mais qui se trouve dans le dossier Fichiers, car je n'ai pas le droit d'y accéder.

Si je copie un fichier qui n'a pas été créé par moi (pas mon programme), je ne peux pas le fermer après la copie avec la fonction FileClose() (pas de poignée), MAIS je peux l'effacer.

C'estpeut-être la raison pour laquelle les dossiers contenant des fichiers copiés et supprimés ne sont pas supprimés par la fonction FolderClean(). Probablement, parce qu'ils n'ont pas été fermés après avoir été copiés.

MAIS ILS NE PEUVENT PAS ÊTRE FERMÉS CAR ILS N'ONT PAS DE POIGNÉE !

:)))

 

Questions pour les développeurs :

1. Comment puis-je obtenir le handle du fichier qui a été créé dans le dossier Files avant de charger le script ?

2. Le problème de la suppression des dossiers à l'aide de FolderClean(), après avoir effacé les fichiers qu'ils contenaient et qui avaient été précédemment copiés dans un autre dossier et non fermés après la copie (parce qu'il n'y a pas de poignée), pourrait-il avoir la cause ci-dessus ?

 
Реter Konow:

Questions pour les développeurs :

1. Comment puis-je obtenir le handle du fichier qui a été créé dans le dossier Files avant de charger le script ?

2. Le problème de la suppression des dossiers à l'aide de la fonction FolderClean(), après avoir effacé les fichiers qu'ils contenaient et qui avaient été précédemment copiés dans un autre dossier et non fermés après la copie (parce qu'il n'y a pas de poignée), pourrait-il avoir la raison ci-dessus ?


C'est en quelque sorte la base du système d'exploitation. Si une application a ouvert un fichier en écriture, ni ce fichier ni le dossier qui le contient ne peuvent être supprimés. Essayez d'ouvrir un fichier dans Word, puis utilisez les outils du système d'exploitation pour supprimer le dossier dans lequel il se trouve. Que va-t-il se passer ? Vous ne pourrez pas le faire, car vous n'y aurez pas accès.

Eh bien, vous pouvez obtenir la poignée de fichier. Mais à quoi servirait une telle action ? Après tout, si le fichier est ouvert par une autre application, vous verrez la déclaration précédente. Nous n'obtiendrons qu'un handle qui est valide dans notre application.

 
Ihor Herasko:

C'est en quelque sorte la base du système d'exploitation. Si une application a ouvert un fichier en écriture, ni le fichier ni le dossier qui le contient ne peuvent être supprimés. Essayez d'ouvrir un fichier dans Word, puis utilisez le système d'exploitation pour supprimer le dossier dans lequel il se trouve. Que va-t-il se passer ? Vous ne pourrez pas le faire, car vous n'y aurez pas accès.

Eh bien, vous pouvez obtenir la poignée de fichier. Mais à quoi servirait une telle action ? Après tout, si le fichier est ouvert par une autre application, vous verrez la déclaration précédente. Et nous ne pouvons obtenir qu'une poignée qui est valide dans notre application particulière.

Le fichier est ouvert par mon application (navigateur de fichiers) pour être écrasé dans un autre dossier.

Après l'écrasement, je dois fermer le fichier mais je ne peux pas - (pas de poignée) donc j'efface simplement le fichier.

Il n'y a pas de poignée car le fichier a été créé on ne sait pas quand et par qui.

En même temps, le fichier existe dans le dossier Fichiers et peut être copié dans un autre dossier, puis effacé.

Mais après la copie, le fichier ne peut pas être fermé. Il n'y a pas de poignée.

C'est probablement la raison pour laquelle l'effacement ultérieur des dossiers FolderClean() avec les fichiers effacés, ne fonctionne pas.


Question : comment puis-je obtenir le handle de ce fichier dans le programme MQL ?

 

Cela ne semble pas être un problème que nous avons déjà rencontré dans la communauté... :)

OK, je vais trouver quelque chose.

Je le fais toujours.)

 

Démystifier les mythes.

Donc, les données terminales sur le système d'exploitation :

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

Au moment des tests, le dossier "test" a été créé dans [dossier de données]\MQL5\Files et le fichier texte "source.txt" avec le contenu suivant y a été créé :

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 
   );


Donc, étape 1 : Copier le fichier "source.txt" dans un autre en utilisant les outils MQL5

Script :

//--- 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);
  }
//+------------------------------------------------------------------+


Étape 2 : Nettoyage du dossier "test" à l'aide des outils MQL5

Script :

//+------------------------------------------------------------------+
//|                                                  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;
  }
//+------------------------------------------------------------------+


Étape 3 : Suppression du dossier "test" à l'aide des outils 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());
//--- 
  }
//+------------------------------------------------------------------+


Quel est le problème ? Tout fonctionne.

Dossiers :
 
Vladimir Karputov:

Quel est le problème ? Tout fonctionne.

Merci pour cet exemple. Je vais trouver une solution demain matin. Je n'ai pas l'énergie pour le moment).

Je vais tout tester et vous donner une réponse.


Ajouté :

Vous avez cité trois scripts différents ici.

J'ai un programme et la copie, l'effacement des fichiers et des dossiers se fait dans une fonction en deux cycles.

Entrez dans le premier cycle : les fichiers sources sont d'abord copiés dans un autre dossier, puis ces fichiers sources sont effacés. Quitter le premier cycle.

Entrez dans la deuxième boucle : Nous effaçons le dossier source avec FolderClean() et effaçons le dossier source avec -FolderDelete().


Nous regardons ensuite dans le navigateur de fichiers du méta-éditeur et constatons que le dossier source a été partiellement effacé. Les sous-dossiers qui ne contenaient aucun fichier ont été complètement effacés et ceux qui contenaient quelques fichiers ne sont pas effacés, mais sont vides.

Essayer de supprimer des dossiers manuellement - nous l'avons :



Ensuite, nous fermons le terminal et le relançons. On constate que certains sous-dossiers ont disparu d'eux-mêmes, d'autres sont restés. Nous les effaçons manuellement sans aucun problème. Cette fois-ci.

Raison: