Ein Ordner wird nicht gelöscht, wenn er nicht geschlossene Dateien enthält. - Seite 8

 

Ich werde später ein Skript veröffentlichen, das das Problem reproduziert.

Wenn das Problem irgendwie gelöst ist, werde ich alles im Detail erklären.

 
Реter Konow:

1. Das Handle wird nur für die Funktion FileClose benötigt. Ich öffne die Datei nicht. Sie wurde vor mir geschaffen. Ich kopiere sie einfach und lösche sie. Ich kann sie nicht schließen, weil es keinen Griff gibt.

2. Das Dateihandle wird für das Kopieren (FileCopy) und das Verschieben (FileMove) nicht benötigt. Sehen Sie sich die Dokumentation an.

3. Wenn ich eine Datei öffne, die von einer anderen Person mit der Funktion FileOpen erstellt wurde, erhalte ich nicht deren Handle. Es ist noch gar nicht bekannt, welchen Griff ich bekommen werde. Es kann seine sein oder auch eine ganz andere. Ich habe versucht, das Handle einer anderen Datei zu bekommen, damit ich sie nach dem Kopiervorgang mit FileClose schließen kann. Es hat nicht geklappt.

4. Beim Kopieren wird der Griff nicht benötigt. Sie wird ohne Probleme kopiert. Die Datei wird jedoch automatisch zum Kopieren geöffnet. Außerdem kann ich die Datei nicht mit FileClose schließen, da es kein Handle gibt. Dies ist wahrscheinlich der Grund, warum FolderClean nach dem Löschen der kopierten Dateien nicht mehr funktioniert.

5. Woher wissen Sie, dass die Datei nach dem Kopieren nicht geöffnet ist? Sie wurde nicht explizit mit der Funktion FileOpen geöffnet, aber sie wurde mit kopiert, was bedeutet, dass sie geöffnet ist. Daher bleibt sie nach dem Kopieren und sogar nach dem Löschen offen. Wahrscheinlich.

Ein Dateihandle wird nicht nur benötigt, um eine Datei zu schließen, sondern auch, um eine Datei zu lesen und in sie zu schreiben, einen Dateizeiger zu verwalten, um von einer bestimmten Zeile zu lesen oder in eine bestimmte Zeile zu schreiben. Weitere Funktionen, die ein Dateihandle benötigen, finden Sie in der Dokumentation.

2. Ich konnte Ihnen nicht sagen, dass Sie zum Kopieren oder Verschieben einer Datei einen Zugriff auf diese Datei benötigen? Sie haben etwas missverstanden.

Wenn Sie eine Datei öffnen, egal von wem oder wann sie erstellt wurde, erhalten Sie ihr Handle, wenn FileOpen ausgeführt wird.

Ich vermute, Sie verstehen nicht, was ein Griff ist. Nehmen Sie 2 Dateien für ein Experiment, Sie können sie bereit haben, Sie können sie zum Schreiben öffnen und ihre Griffe erhalten. Sie werden sich um eins unterscheiden. Dann kehren Sie die Reihenfolge des Öffnens dieser Dateien um, und Sie sehen dieselben Handles, die aber zu unterschiedlichen Dateien gehören. Zweite Möglichkeit: Öffnen Sie eine Datei, erhalten Sie das Handle = 1, schließen Sie diese Datei und öffnen Sie eine andere... und das Handle der anderen Datei wird ebenfalls =1 sein.

Ein Handle ist die Nummerierung der Dateien innerhalb des Programms und hat nichts mit dem Inhalt der Datei oder ihren anderen Attributen zu tun.

4. Die Datei wird während des Kopierens nicht geöffnet. Und wenn Sie beim Kopieren eine Datei lesen und den gesamten Inhalt in eine andere Datei schreiben, müssen die Handles dieser Dateien in die entsprechenden Variablen gesetzt werden, um diese Dateien weiter bearbeiten zu können.

5. Das Kopieren einer Datei kann einige Millisekunden dauern, genau so lange, wie das Speichern auf der Festplatte dauert. Von dort aus ist er so frei wie ein Vogel am Himmel... Keine Chance, dass etwas passiert.

 

Ich freue mich, berichten zu können, dass das Problem vollständig gelöst ist).

Der Grund dafür:

Beim Erstellen einer Kopie der Dateihierarchie im Array, um sie in einem brauchbaren Dateinavigator wiederzugeben, liest eine spezielle Funktion diese Hierarchie mit FileFindFirst() und FileFindNext().

Ursprünglich wurde nach dem Durchsuchen jedes Ordners am Ende der Schleife die Funktion FileFindClose() aufgerufen, um das Suchhandle für jeden einzelnen Ordner zu schließen.

Offensichtlich habe ich aufgrund langer und komplexer Manipulationen mit der Funktion, die die Dateihierarchie liest, diesen Eintrag FileFindClose() versehentlich gelöscht und es nicht bemerkt. Die Leistung meines Navigators wurde dadurch nicht beeinträchtigt, bis ich versuchte, Ordner umzubenennen. Damit fing das Problem an.

Wie sich herausstellte, hatten die Akten überhaupt nichts mit diesem Fall zu tun. Natürlich ist es sehr hilfreich, dass ich gelernt habe, dass sie geschlossen werden müssen, auch wenn keine Operationen an ihnen durchgeführt wurden. Das wird mich in Zukunft davor bewahren, dieselben Fehler zu machen.


Der Grund, warum meine FolderClean()-Funktion nicht funktionierte, war, dass lange bevor ich sie verwendete, während der Initialisierungsphase des Programms, eine andere Funktion die FileFindFirst()-Suchhandles nach dem Scannen von Ordnern nicht schloss.

Wie sich herausstellte, sind diese Dinge miteinander verbunden...


Ich habe ein Skript erstellt, um das Problem zu reproduzieren, aber aus irgendeinem Grund wird das Problem in diesem Skript nicht reproduziert. Das heißt, in meinem Programm wirkt sich das Hinzufügen/Entfernen der Zeile "FileFindClose(search_handle)" auf das Problem aus, aber im Skript tut es das aus irgendeinem Grund nicht.

Ich füge das Skript unten an. Erstellen Sie einen Ordner "1" im Ordner "Dateien" und legen Sie dort beliebige andere Ordner oder Dateien ab. Wenn Sie die Zeile "FileFindClose(search_handle)" auskommentieren, löscht das Skript den Ordner trotzdem, aber in meinem Programm werden die Ordner ohne diese Zeile nicht gelöscht. Der Grund dafür ist nicht klar.

//+------------------------------------------------------------------+
//|                                             Demo_FolderClean.mq4 |
//|                                                      Peter Konow |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Peter Konow"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//Данный скрипт, сразу после загрузки должен стереть все содержимое 
//папки "1\\" внутри директории "Files".
//Однако, если хэндл поиска, открытый сразу после запуска скрипта функцией
//"FileFindFirst()" не закрыт, то скрипт не сможет стереть папку "1\\".

//Данный скрипт создан для демонстрации взаимосвязи закрытия хэндла поиска
//возвращаемого функцией "FileFindFirst()" и успешной работы функции "FolderClean()".
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   
   //---- Переменная необходимая для функции  "FileFindFirst()" 
   string file_name;
   //-----------------------------
   //Открываем поиск внутри папки "1\\".
   //-----------------------------
   long search_handle=FileFindFirst("1\\",file_name); 
   //--- проверим, успешно ли отработала функция FileFindFirst() 
   if(search_handle!=INVALID_HANDLE) 
     { 
      int i = 0;
      //--- в цикле проверим являются ли переданные строки именами файлов или директорий 
      do 
        { 
         ResetLastError(); 
         //--- если это файл, то функция вернет true, а если директория, то функция генерирует ошибку ERR_FILE_IS_DIRECTORY 
         FileIsExist(file_name); 
         PrintFormat("%d : %s name = %s",i,GetLastError()==ERR_FILE_IS_DIRECTORY ? "Directory" : "File",file_name); 
         i++; 
        } 
      while(FileFindNext(search_handle,file_name)); 
      //--- закрываем хэндл поиска 
      FileFindClose(search_handle); 
     } 
   else 
      Print("Files not found!");/**/ 
   //-----------------------------
   //Переходим к очищению папки "1\\" и ее последующему стиранию.
   //-----------------------------
   if(!FolderClean("1\\"))
   //--- Очищаем папку.
     Print("FolderClean  Error ",GetLastError());
   
   else 
     {//--- Стираем папку.
      if(!FolderDelete("1\\"))
        Print("FolderDelete  Error ",GetLastError());
      
      else 
       Print("Folder was cleaned and removed");
     } 
  }
//+------------------------------------------------------------------+
Grund der Beschwerde: