Ich habe mich gefragt, was es damit auf sich hat. Wenn ich Zeit habe, werde ich es mir ansehen... Natürlich hätte ich gerne eine präzisere Formulierung der Aufgabe
Bitte machen Sie weiter - solange Sie in dem faszinierenden Genre der "Fiktion" schreiben. Spätestens auf Seite 40 sind Sie hoffentlich bei der Fachliteratur angelangt.
Der Fehler ist implizit. Im Moment ist es schwierig, mehr technische Details zu nennen.
Ich habe alle Dateien gelöscht, auch ohne sie explizit zu schließen. Gelöscht, weil ich sie nicht erstellt habe und sie sich vorher im Ordner "Dateien" befanden.
Der Punkt ist, dass wir zum Löschen einer Datei deren Handle benötigen. Wenn wir diese Datei jedoch nicht erstellt, sondern nur in den Ordner "Dateien" gelegt haben, können wir ihr Handle nicht erhalten und sie daher auch nicht mit FileClose() schließen.
Gleichzeitig können wir sie aber immer noch kopieren oder löschen. Allerdings kann der Ordner danach weder programmatisch noch manuell gelöscht werden. Manuell nur nach einem Neustart des Terminals.
Ich werde später versuchen, das Problem anhand von Beispielen deutlicher darzustellen.
Der Code muss nur vollständig sein. Wenn die Datei geöffnet ist, muss sie vor dem Herunterfahren des Computers oder dem Schließen von MT4/5 geschlossen werden. Und vorzugsweise muss der Griff von jeder Stelle des Programms aus zugänglich sein. Dies ist meine Meinung. Noch besser ist es, die Datei sofort zu schließen, nachdem Sie eine Lese-/Schreiboperation mit ihr durchgeführt haben, oder auch wenn Sie nichts mit ihr zu tun haben.
Die Beispieldokumentation scheint zu zeigen, wie man es nicht machen sollte.
Es ist auch sehr wichtig, daran zu denken, dass beim Schreiben in eine Datei die geschriebene Datei nur gelesen werden kann, indem alle im Datei-E/A-Puffer verbliebenen Daten mit FileFlushauf die Festplatte geschrieben werdenoder indem die Datei geschlossen wird. Wenn Sie die Datei schließen, werden die Daten auf die Festplatte zurückgesetzt.
Zusammenfassung: Wenn Sie eine Datei öffnen, vergessen Sie nicht, sie wieder zu schließen. Und der Datei-Handle geht nicht verloren.
Der Code muss einfach vollständig sein. Wenn eine Datei geöffnet ist, muss sie geschlossen werden, bevor der Computer ausgeschaltet oder MT4/5 geschlossen wird. Und der Griff sollte möglichst von jeder Stelle des Programms aus erreichbar sein. Dies ist IMHO. Noch besser ist es, die Datei sofort nach dem Lese-/Schreibvorgang zu schließen, auch wenn Sie nichts mit ihr zu tun hatten.
Die Beispieldokumentation scheint zu zeigen, wie man es nicht machen sollte.
Es ist auch sehr wichtig, daran zu denken, dass beim Schreiben in eine Datei die geschriebene Datei nur gelesen werden kann, indem alle im Datei-E/A-Puffer verbliebenen Daten mit FileFlushauf die Festplatte geschrieben werdenoder indem die Datei geschlossen wird. Während des Schließvorgangs werden die Daten zwangsweise auf die Festplatte zurückgesetzt.
Zusammenfassung: Wenn Sie eine Datei öffnen, vergessen Sie nicht, sie wieder zu schließen. Und der Datei-Handle geht nicht verloren.
Auch hier kann ich eine von meinem Programm erstellte Datei mit der Funktion FileClose() schließen - ich habe ihr Handle.
Ich kann eine Datei, die von einem anderen Benutzer erstellt wurde, sich aber im Ordner "Dateien" befindet, nicht schließen, weil ich keinen Zugriff darauf habe.
Wenn ich eine Datei kopiere, die nicht von mir erstellt wurde (nicht mein Programm), dann kann ich sie nach dem Kopieren nicht mit der Funktion FileClose() schließen (kein Handle), ABER ich kann sie löschen.
Vielleicht ist das der Grund, warum Ordner mit kopierten und gelöschten Dateien nicht von der Funktion FolderClean() gelöscht werden. Wahrscheinlich, weil sie nicht geschlossen wurden, nachdem sie kopiert worden waren.
ABER SIE KÖNNEN NICHT GESCHLOSSEN WERDEN, WEIL SIE KEINEN GRIFF HABEN!
1. Wie erhalte ich den Handle der Datei, die vor dem Laden des Skripts im Ordner "Files" erstellt wurde?
2. Könnte das Problem des Löschens von Ordnern mit FolderClean(), nachdem Dateien darin gelöscht wurden, die zuvor in einen anderen Ordner kopiert und nach dem Kopieren nicht geschlossen wurden (weil es keinen Handle gibt), die oben genannte Ursache haben?
1. Wie erhalte ich den Handle der Datei, die vor dem Laden des Skripts im Ordner "Files" erstellt wurde?
2. Könnte das Problem des Löschens von Ordnern mit der Funktion FolderClean(), nachdem Dateien darin gelöscht wurden, die zuvor in einen anderen Ordner kopiert und nach dem Kopieren nicht geschlossen wurden (weil es keinen Handle gibt), den oben genannten Grund haben?
Das sind sozusagen die Grundlagen des Betriebssystems. Wenn eine Anwendung eine Datei zum Schreiben geöffnet hat, kann weder diese Datei noch der Ordner, der sie enthält, gelöscht werden. Versuchen Sie, eine Datei in Word zu öffnen und dann mit den Werkzeugen des Betriebssystems den Ordner zu löschen, in dem sie sich befindet. Was wird geschehen? Das werden Sie nicht können, weil Sie keinen Zugang dazu haben werden.
Nun, Sie können den Datei-Handle bekommen. Aber was würde eine solche Aktion bringen? Denn wenn die Datei von einer anderen Anwendung geöffnet wird, sehen Sie die vorherige Anweisung. Wir erhalten nur ein Handle, das in unserer Anwendung gültig ist.
Das sind sozusagen die Grundlagen des Betriebssystems. Wenn eine Anwendung eine Datei zum Schreiben geöffnet hat, können weder die Datei noch der Ordner, der sie enthält, gelöscht werden. Versuchen Sie, eine Datei in Word zu öffnen und dann mit Hilfe des Betriebssystems den Ordner zu löschen, in dem sie sich befindet. Was wird geschehen? Das werden Sie nicht können, weil Sie keinen Zugang dazu haben werden.
Nun, Sie können den Datei-Handle bekommen. Aber was würde eine solche Maßnahme bringen? Denn wenn die Datei von einer anderen Anwendung geöffnet wird, sehen Sie die vorherige Anweisung. Und wir können nur einen Handle erhalten, der in unserer speziellen Anwendung gültig ist.
Die Datei wird von meiner Anwendung (Datei-Navigator) geöffnet, um in einen anderen Ordner überschrieben zu werden.
Nach dem Überschreiben muss ich die Datei schließen, kann das aber nicht (kein Handle), also lösche ich die Datei einfach.
Es gibt keinen Handle, da nicht bekannt ist, wann und von wem die Datei erstellt wurde.
Gleichzeitig existiert die Datei im Ordner "Dateien" und kann in einen anderen Ordner kopiert und dann gelöscht werden.
Nach dem Kopieren kann die Datei jedoch nicht geschlossen werden. Es gibt keinen Griff.
Dies ist wahrscheinlich der Grund, warum das weitere Löschen von Ordnern mit FolderClean() mit gelöschten Dateien nicht funktioniert.
Frage: Wie bekomme ich das Handle dieser Datei in das MQL-Programm?
2017.08.2822:20:53.474 Terminal MetaTrader 5 x64 build 1653 started (MetaQuotes Software Corp.)
2017.08.2822: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:002017.08.2822:20:53.476 Terminal C:\Users\barab\AppData\Roaming\MetaQuotes\Terminal\D0E8209F77C8CF37AD8BF550E51FF075
Zum Zeitpunkt der Tests wurde der Ordner "test" in [data folder]\MQL5\Files erstellt und darin die Textdatei "source.txt" mit folgendem Inhalt angelegt:
FileCopy
The function copies the original file from a local or shared folder to another file.
boolFileCopy(
conststring src_file_name, // Name of a source file int common_flag, // Location conststring dst_file_name, // Name of the destination file int mode_flags // Access mode
);
Schritt 1: Kopieren der Datei "source.txt" in eine andere Datei mit den MQL5-Tools
Drehbuch:
//--- display the window of input parameters when launching the script #property script_show_inputs//--- input parameters inputstring InpSrc="test\\source.txt"; // source inputstring InpDst="test\\destination.txt"; // copy inputint InpEncodingType=FILE_ANSI; // ANSI=32 or UNICODE=64 //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ voidOnStart()
{
//--- 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!");
elsePrint("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!");
elsePrint("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!");
elsePrint("File is not copied!");
}
//--- receive InpSrc file copy
FileDisplay(InpDst);
}
//+------------------------------------------------------------------+ //| Read the file contents | //+------------------------------------------------------------------+ bool FileDisplay(conststring 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);
}
//+------------------------------------------------------------------+
Schritt 2: Bereinigung des Ordners "test" mit MQL5-Tools
Was ist denn so schlimm daran? Alles funktioniert.
Vielen Dank für dieses Beispiel. Ich werde es morgen früh herausfinden. Ich habe im Moment nicht die Energie dafür).
Ich werde alles prüfen und Ihnen eine Antwort geben.
Hinzugefügt:
Sie haben hier drei verschiedene Skripte zitiert.
Ich habe ein Programm und das Kopieren, Löschen von Dateien und Ordnern geschieht innerhalb einer Funktion in zwei Zyklen.
Geben Sie den ersten Zyklus ein: Zuerst werden die Quelldateien in einen anderen Ordner kopiert, dann werden diese Quelldateien gelöscht. Beenden Sie den ersten Zyklus.
Wir beginnen mit der zweiten Schleife: Wir leeren den Quellordner mit FolderClean() und löschen den Quellordner mit -FolderDelete().
Dann sehen wir im Dateinavigator des Meta-Editors, dass der Quellordner teilweise gelöscht wurde. Unterordner, die keine Dateien enthielten, wurden vollständig gelöscht, und diejenigen, die einige Dateien enthielten, wurden nicht gelöscht, sondern sind leer.
Versuchen Sie, Ordner manuell zu entfernen - wir haben es geschafft:
Dann schließen wir das Terminal und starten es erneut. Wir sehen, dass einige Unterordner von selbst verschwunden sind, andere sind geblieben. Wir löschen sie manuell und ohne Probleme. Dieses Mal.
Bitte machen Sie weiter - solange Sie in dem faszinierenden Genre der "Fiktion" schreiben. Spätestens auf Seite 40 sind Sie hoffentlich bei der Fachliteratur angelangt.
Ich habe alle Dateien gelöscht, auch ohne sie explizit zu schließen. Gelöscht, weil ich sie nicht erstellt habe und sie sich vorher im Ordner "Dateien" befanden.
Der Punkt ist, dass wir zum Löschen einer Datei deren Handle benötigen. Wenn wir diese Datei jedoch nicht erstellt, sondern nur in den Ordner "Dateien" gelegt haben, können wir ihr Handle nicht erhalten und sie daher auch nicht mit FileClose() schließen.
Gleichzeitig können wir sie aber immer noch kopieren oder löschen. Allerdings kann der Ordner danach weder programmatisch noch manuell gelöscht werden. Manuell nur nach einem Neustart des Terminals.
Ich werde später versuchen, das Problem anhand von Beispielen deutlicher darzustellen.
Der Code muss nur vollständig sein. Wenn die Datei geöffnet ist, muss sie vor dem Herunterfahren des Computers oder dem Schließen von MT4/5 geschlossen werden. Und vorzugsweise muss der Griff von jeder Stelle des Programms aus zugänglich sein. Dies ist meine Meinung. Noch besser ist es, die Datei sofort zu schließen, nachdem Sie eine Lese-/Schreiboperation mit ihr durchgeführt haben, oder auch wenn Sie nichts mit ihr zu tun haben.
Die Beispieldokumentation scheint zu zeigen, wie man es nicht machen sollte.
Es ist auch sehr wichtig, daran zu denken, dass beim Schreiben in eine Datei die geschriebene Datei nur gelesen werden kann, indem alle im Datei-E/A-Puffer verbliebenen Daten mit FileFlush auf die Festplatte geschrieben werdenoder indem die Datei geschlossen wird. Wenn Sie die Datei schließen, werden die Daten auf die Festplatte zurückgesetzt.
Zusammenfassung: Wenn Sie eine Datei öffnen, vergessen Sie nicht, sie wieder zu schließen. Und der Datei-Handle geht nicht verloren.
Der Code muss einfach vollständig sein. Wenn eine Datei geöffnet ist, muss sie geschlossen werden, bevor der Computer ausgeschaltet oder MT4/5 geschlossen wird. Und der Griff sollte möglichst von jeder Stelle des Programms aus erreichbar sein. Dies ist IMHO. Noch besser ist es, die Datei sofort nach dem Lese-/Schreibvorgang zu schließen, auch wenn Sie nichts mit ihr zu tun hatten.
Die Beispieldokumentation scheint zu zeigen, wie man es nicht machen sollte.
Es ist auch sehr wichtig, daran zu denken, dass beim Schreiben in eine Datei die geschriebene Datei nur gelesen werden kann, indem alle im Datei-E/A-Puffer verbliebenen Daten mit FileFlush auf die Festplatte geschrieben werdenoder indem die Datei geschlossen wird. Während des Schließvorgangs werden die Daten zwangsweise auf die Festplatte zurückgesetzt.
Zusammenfassung: Wenn Sie eine Datei öffnen, vergessen Sie nicht, sie wieder zu schließen. Und der Datei-Handle geht nicht verloren.
Auch hier kann ich eine von meinem Programm erstellte Datei mit der Funktion FileClose() schließen - ich habe ihr Handle.
Ich kann eine Datei, die von einem anderen Benutzer erstellt wurde, sich aber im Ordner "Dateien" befindet, nicht schließen, weil ich keinen Zugriff darauf habe.
Wenn ich eine Datei kopiere, die nicht von mir erstellt wurde (nicht mein Programm), dann kann ich sie nach dem Kopieren nicht mit der Funktion FileClose() schließen (kein Handle), ABER ich kann sie löschen.
Vielleicht ist das der Grund, warum Ordner mit kopierten und gelöschten Dateien nicht von der Funktion FolderClean() gelöscht werden. Wahrscheinlich, weil sie nicht geschlossen wurden, nachdem sie kopiert worden waren.
ABER SIE KÖNNEN NICHT GESCHLOSSEN WERDEN, WEIL SIE KEINEN GRIFF HABEN!
:)))
Fragen an die Entwickler:
1. Wie erhalte ich den Handle der Datei, die vor dem Laden des Skripts im Ordner "Files" erstellt wurde?
2. Könnte das Problem des Löschens von Ordnern mit FolderClean(), nachdem Dateien darin gelöscht wurden, die zuvor in einen anderen Ordner kopiert und nach dem Kopieren nicht geschlossen wurden (weil es keinen Handle gibt), die oben genannte Ursache haben?
Fragen an die Entwickler:
1. Wie erhalte ich den Handle der Datei, die vor dem Laden des Skripts im Ordner "Files" erstellt wurde?
2. Könnte das Problem des Löschens von Ordnern mit der Funktion FolderClean(), nachdem Dateien darin gelöscht wurden, die zuvor in einen anderen Ordner kopiert und nach dem Kopieren nicht geschlossen wurden (weil es keinen Handle gibt), den oben genannten Grund haben?
Das sind sozusagen die Grundlagen des Betriebssystems. Wenn eine Anwendung eine Datei zum Schreiben geöffnet hat, kann weder diese Datei noch der Ordner, der sie enthält, gelöscht werden. Versuchen Sie, eine Datei in Word zu öffnen und dann mit den Werkzeugen des Betriebssystems den Ordner zu löschen, in dem sie sich befindet. Was wird geschehen? Das werden Sie nicht können, weil Sie keinen Zugang dazu haben werden.
Nun, Sie können den Datei-Handle bekommen. Aber was würde eine solche Aktion bringen? Denn wenn die Datei von einer anderen Anwendung geöffnet wird, sehen Sie die vorherige Anweisung. Wir erhalten nur ein Handle, das in unserer Anwendung gültig ist.
Das sind sozusagen die Grundlagen des Betriebssystems. Wenn eine Anwendung eine Datei zum Schreiben geöffnet hat, können weder die Datei noch der Ordner, der sie enthält, gelöscht werden. Versuchen Sie, eine Datei in Word zu öffnen und dann mit Hilfe des Betriebssystems den Ordner zu löschen, in dem sie sich befindet. Was wird geschehen? Das werden Sie nicht können, weil Sie keinen Zugang dazu haben werden.
Nun, Sie können den Datei-Handle bekommen. Aber was würde eine solche Maßnahme bringen? Denn wenn die Datei von einer anderen Anwendung geöffnet wird, sehen Sie die vorherige Anweisung. Und wir können nur einen Handle erhalten, der in unserer speziellen Anwendung gültig ist.
Die Datei wird von meiner Anwendung (Datei-Navigator) geöffnet, um in einen anderen Ordner überschrieben zu werden.
Nach dem Überschreiben muss ich die Datei schließen, kann das aber nicht (kein Handle), also lösche ich die Datei einfach.
Es gibt keinen Handle, da nicht bekannt ist, wann und von wem die Datei erstellt wurde.
Gleichzeitig existiert die Datei im Ordner "Dateien" und kann in einen anderen Ordner kopiert und dann gelöscht werden.
Nach dem Kopieren kann die Datei jedoch nicht geschlossen werden. Es gibt keinen Griff.
Dies ist wahrscheinlich der Grund, warum das weitere Löschen von Ordnern mit FolderClean() mit gelöschten Dateien nicht funktioniert.
Frage: Wie bekomme ich das Handle dieser Datei in das MQL-Programm?
Dies scheint ein Problem zu sein, mit dem die Gemeinschaft noch nicht konfrontiert wurde... :)
OK, ich werde mir etwas einfallen lassen.
Das tue ich immer.)
Entlarvung von Mythen.
Also, Terminaldaten auf dem Betriebssystem:
Zum Zeitpunkt der Tests wurde der Ordner "test" in [data folder]\MQL5\Files erstellt und darin die Textdatei "source.txt" mit folgendem Inhalt angelegt:
Schritt 1: Kopieren der Datei "source.txt" in eine andere Datei mit den MQL5-Tools
Drehbuch:
Schritt 2: Bereinigung des Ordners "test" mit MQL5-Tools
Drehbuch:
Schritt 3: Löschen des Ordners "test" mit den MQL5-Tools
Wo liegt das Problem? Alles funktioniert.
Was ist denn so schlimm daran? Alles funktioniert.
Vielen Dank für dieses Beispiel. Ich werde es morgen früh herausfinden. Ich habe im Moment nicht die Energie dafür).
Ich werde alles prüfen und Ihnen eine Antwort geben.
Hinzugefügt:
Sie haben hier drei verschiedene Skripte zitiert.
Ich habe ein Programm und das Kopieren, Löschen von Dateien und Ordnern geschieht innerhalb einer Funktion in zwei Zyklen.
Geben Sie den ersten Zyklus ein: Zuerst werden die Quelldateien in einen anderen Ordner kopiert, dann werden diese Quelldateien gelöscht. Beenden Sie den ersten Zyklus.
Wir beginnen mit der zweiten Schleife: Wir leeren den Quellordner mit FolderClean() und löschen den Quellordner mit -FolderDelete().
Dann sehen wir im Dateinavigator des Meta-Editors, dass der Quellordner teilweise gelöscht wurde. Unterordner, die keine Dateien enthielten, wurden vollständig gelöscht, und diejenigen, die einige Dateien enthielten, wurden nicht gelöscht, sondern sind leer.
Versuchen Sie, Ordner manuell zu entfernen - wir haben es geschafft:
Dann schließen wir das Terminal und starten es erneut. Wir sehen, dass einige Unterordner von selbst verschwunden sind, andere sind geblieben. Wir löschen sie manuell und ohne Probleme. Dieses Mal.