Arbeiten mit Dateien. - Seite 4

 

TheXpert:

OMG! Wo der Output ist, ist er unsinnig. So kommt es zu Behauptungen wie "OOP ist schneller" oder "Indikatoren sind langsam, wir sollten den gesamten Code in Expert Advisor einbauen".

Ich verstehe, dass nicht alles wie geplant funktioniert. Zumindest sollte die normale Verwendung von FileFlush() schneller sein als FileClose().

Ich bin aber nach wie vor der Meinung, dass man solche Dinge nicht in Schleifen packen sollte; sie werden ohnehin nicht viel nützen.

Und wenn ich das Beispiel für MQL4 richtig verstanden habe, istder Aufruf von FileFlush() zwischen zwei Schleifen platziert (es schien mir, dass es eine Bremse in einer Schleife wäre).

  int bars_count=Bars;
  int handle=FileOpen("mydat.csv",FILE_CSV|FILE_WRITE);
  if(handle>0)
    {
     FileWrite(handle, "#","OPEN","CLOSE","HIGH","LOW");
     for(int i=0;i<bars_count;i++)
       FileWrite(handle, i+1,Open[i],Close[i],High[i], Low[i]);
     

FileFlush(handle);

     ...      for(int i=0;i<bars_count;i++)        FileWrite(handle, i+1,Open[i],Close[i],High[i], Low[i]);      FileClose(handle);     }

Also, wenn ich die Logik der Entwickler richtig verstehe, sollte die Datei in OnInit / Constructor der Hauptklasse geöffnet werden (vielleicht nicht nur im Konstruktor) und in OnDeint / Destructive der Hauptklasse geschlossen werden.

Inallen anderen Fällen verwenden Sie statt FileClose FileFlush (nach FileWrite und nach Schleifen).


 

TheXpert:

Yedelkin:

Ich habe die Leitungen gemäß der Dokumentation vertauscht:

         FileFlush(handle_file);
         FileWrite(handle_file,t);

Wo steht das in der Dokumentation?

Es gibt einen solchen Satz in der MQL5-Referenz:

FileFlush

Hinweis

Die Funktion FileFlush() sollte zwischen Operationen zum Lesen aus einer Datei und zum Schreiben in eine Datei aufgerufen werden.

Wenn "Schreiben in eine Datei" == FileWrite() Funktion , dann lesen: "Die Funktion FileFlush() muss vor der Funktion FileWrite() aufgerufen werden". Oder haben Sie eine andere Meinung?

TheXpert:

Yedelkin:
Aber ich verstehe immer noch nicht den Sinn des Aufrufs von FileFlush() vor FileWrite().

Wie kann man etwas, das keinen hat, sinnvoll nutzen? Bringen Sie die Reihenfolge der Zeilen zurück zur Startseite und überprüfen Sie sie erneut. Offensichtlich war das in der Dokumentation nicht ganz richtig ausgedrückt.

Es ist gut, wenn man schon im Voraus weiß, was beim Lernen von neuem Material sinnvoll ist und was nicht. Da die Natur uns nicht mit solchen Talenten ausgestattet hat, müssen wir "jede neue Höhe nehmen", testen, Dokumentation und Ergebnisse interpretieren. Ich bin mir nicht einmal sicher, ob die Tests selbst richtig geschrieben sind. Zuerst habe ich intuitiv FileFlush() nach FileWrite() gesetzt , aber nachdem ich das Handbuch noch einmal gelesen habe, habe ich dieses Beispiel gelöscht.

TheXpert:

Interessant:

OMG! Es ist absurd, wo der Ausgang ist. So kommt es zu Behauptungen wie "OOP ist schneller" oder "Indikatoren sind langsam, wir sollten den gesamten Code in einen Expert Advisor packen".

Es wäre schön, wenn auf jede Bewertung von "Ihr Output ist dumm" eine Erklärung folgen würde, was daran dumm ist :) Ansonsten ist es unklar, in welche Richtung man sich mit einer solchen Strenge der Justiz bewegen soll :)

 
TheXpert:

Es hat keinen Sinn, die Änderungen vor ihrem Erscheinen zu verdrängen, denn sie sind noch nicht da :)

Sie werden es nicht glauben, aber genau aus diesem Grund habe ich geschrieben: "Aber ich verstehe den Sinn nicht, FileFlush() vor FileWrite() aufzurufen ", und mich dabei auf die Dokumentation bezogen. Aber ich habe nicht genug Nerven und Wissen, um jede Zeile in der Dokumentation zu hinterfragen :)
... Nun, der Kurs ist klar - wir warten darauf, was die Entwickler sagen werden, wenn wirklich ein Problem entdeckt wird.
 
Yedelkin:

Es gibt einen solchen Satz in der MQL5-Referenz:

Wenn "in eine Datei schreiben" == FileWrite() Funktion , liest sie: "Die Funktion FileFlush() muss vor der Funktion FileWrite() aufgerufen werden".Oder haben Sie eine andere Meinung?

Analysieren wir die "eher unglückliche" Beschreibung und das Beispiel dieser Funktion für MQL4.

void FileFlush( int handle)


Setzt alle im Datei-E/A-Puffer verbliebenen Daten auf die Festplatte zurück.

Hinweis: Die Funktion FileFlush() muss zwischen den Lese- und Schreiboperationen einer Datei aufgerufen werden.
Wenn die Datei geschlossen wird, werden die Daten automatisch auf die Festplatte gespült, so dass es nicht notwendig ist, FileFlush() vor dem Aufruf von FileClose() aufzurufen.

Die hier markierte Zeile ist das Argument für die Notwendigkeit, FileFlush in der Schleife aufzurufen , bevor in die Datei geschrieben wird.

Wenn wir diesen Kommentar jedoch wörtlich verstehen, ergibt sich folgendes:

die Funktion FileFlush() muss zwischen den Operationen des Lesens aus der Datei (beim Lesen ist FileReadXXX) und des Schreibens in die Datei (das Schreiben ist mit FileWrite und FileWriteXXX verbunden) aufgerufen werden.

Beim Schließen der Datei (lesen - wenn FileClose ausgeführt wird), werden die Daten automatisch auf die Festplatte geschrieben (lesen - wenn FileFlush automatisch ausgeführt wird).


Ich denke, die Entwickler haben sich nicht viel um die Korrektheit des Lesens der Hilfe selbst in der MQL4-Version gekümmert; es ist sogar lächerlich, davon zu sprechen, den abgeschnittenen Teil in MQL5 einzufügen.

Zumindest der zweite Satz im obigen Kommentar sollte meiner Meinung nach wie folgt aussehen:

Die Daten werden automatisch auf die Festplatte zurückgesetzt, wenn die Dateigeschlossen wird, so dass es nicht notwendig ist, FileFlush() vor dem Aufruf von FileClose() aufzurufen.

Es ist auch ein wenig unübersichtlich, aber aus gewisser Sicht erklärt es, warum FileFlush nicht vor dem Schließen der Datei mit FileClose verwendet werden sollte.


Das Beispiel ist nicht so einfach, der Text spricht von einer Sache (Verwendung zwischen Lese- und Schreiboperationen), während das Beispiel die Verwendung zwischen zwei Schreiboperationen in Schleifen beschreibt (die Arbeit innerhalb von Schleifen wird in der Hilfe übrigens überhaupt nicht berücksichtigt).

Daher sollte zumindest Folgendes hinzugefügt werden:

1. eine Beschreibung, was dieser Ein-/Ausgabepuffer ist und was in ihm zwischen dem Öffnen einer Datei, dem Lesen eines Datenblocks, dem Schreiben eines Datenblocks und dem Schließen der Datei tatsächlich geschieht.

Dies bezieht sich höchstwahrscheinlich auf den gesamten Abschnitt über Dateioperationen.

2. Nennen Sie ein normal verständliches Beispiel (kann klassenbasiert sein) für die korrekte Verwendung des FileFlush-Aufrufs für einen einzelnen Dateizugriff (z. B. das Schreiben eines Timerwerts).

3 Geben Sie ein normales Beispiel für einen Aufruf bei der Arbeit mit Arrays an. Soweit ich weiß, bezieht sich das in der MQL4-Referenz beschriebene Beispiel auf die Arbeit mit großen Arrays, veranschaulicht dies aber nicht richtig (mit einem Wort - warum eine ziemlich große Menge identischer Daten zweimal in die Datei schreiben, wenn dies auch mehrmals möglich ist).

FileFlush - Документация на MQL4
  • docs.mql4.com
FileFlush - Документация на MQL4
 
Interesting:

Die hier hervorgehobene Zeile ist Ihr Argument für die Notwendigkeit, FileFlush in der Schleife aufzurufen , bevor in die Datei geschrieben wird.

Wenn wir diese Bemerkung jedoch wörtlich verstehen, ergibt sich folgendes:

die Funktion FileFlush() muss zwischen den Operationen des Lesens aus der Datei (beim Lesen ist FileReadXXX) und des Schreibens in die Datei (das Schreiben ist mit FileWrite und FileWriteXXX verbunden) aufgerufen werden.

Beim Schließen der Datei (Lesen - bei Ausführung von FileClose) werden die Daten automatisch auf die Festplatte gespült (Lesen - bei Ausführung von FileFlush).

Ich verstehe, was Sie meinen. Es tut mir leid, dass ich unwissentlich die Operation "aus der Datei lesen" mit der Funktion FileOpen() gleichgesetzt habe (mein Expert Advisor liest nur bei OnInit(), während er während der Verarbeitung von Ticks und benutzerdefinierten Ereignissen nur schreibt; aus diesem Grund habe ich Funktionen wie FileReadXXX() in der Schleife nicht berücksichtigt). Nichtsdestotrotz, FileFlush() vor FileWriteXXX() - das Prinzip ist in beiden Referenzen dasselbe. Und es war keine Argumentation im klassischen Sinne (als Begründung meiner Position), sondern einfach eine Antwort auf die Frage, warum ich diesen Satz gemacht habe.

Wie auch immer, wenn die Entwickler hier nicht antworten, werde ich heute Abend eine Anfrage stellen, mit einem Link zu der Diskussion und den Zwischenergebnissen. Es sind sogar zwei Anträge erforderlich: 1) "Fehler - kein Fehler" und 2) Änderungen in der Dokumentation. Möchten Sie den zweiten Antrag selbst stellen, da Sie sich so intensiv mit dem Thema beschäftigt haben?

 
Yedelkin:

Ich sehe, was ich denke. Ich gestehe, dass ich unwissentlich die Operation "aus der Datei lesen" mit der Funktion FileOpen() gleichgesetzt habe (mein Expert Advisor liest nur bei OnInit(), während er während der Verarbeitung von Ticks und Benutzerereignissen nur schreibt; aus diesem Grund habe ich Funktionen wie FileReadXXX() in der Schleife nicht berücksichtigt). Nichtsdestotrotz, FileFlush() vor FileWriteXXX() - das Prinzip ist in beiden Referenzen dasselbe. Und es war keine Argumentation im klassischen Sinne (als Begründung meiner Position), sondern einfach eine Antwort auf die Frage, warum ich diesen Satz gemacht habe.

Wie auch immer, wenn die Entwickler hier nicht antworten, werde ich heute Abend eine Anfrage stellen, mit einem Link zu der Diskussion und den Zwischenergebnissen. Es sind sogar zwei Anträge erforderlich: 1) "Fehler - kein Fehler" und 2) Änderungen in der Dokumentation. Möchten Sie den zweiten Antrag selbst stellen, da Sie so tief in das Thema eingedrungen sind?

1. Ich würde es wahrscheinlich gerne tun, wenn ich verstehen würde, was die Entwickler sagen wollen und wo.

Manchmal wird ein E/A-Puffer erwähnt, aber nicht genau beschrieben. Oder weiß jeder hier, was der FILE I/O-Puffer ist?

Ist es schwierig, eine normale Beschreibung dieses Problems in das Kapitel über Dateioperationen aufzunehmen? Oder in der ganzen Welt nach einer Antwort auf die Frage suchen, was die Entwickler vorhatten?

Ich verstehe, dass der Umfang der Hilfe begrenzt ist, aber warum sollten wir uns über diejenigen lustig machen, die gerade erst anfangen, MQL zu lernen?

2. Warum wird dieser Puffer nur in der Hilfe zu dieser Funktion erwähnt, warum nicht an anderer Stelle im Abschnitt über Dateioperationen?

3) Nehmen wir an, ich habe eine Vorstellung von genau diesem Puffer für die Ein- und Ausgabe, ungefähr in dieser Form

Der Begriff des Input-Output-Puffers ist mit dem Dateisystem verbunden. Die Ein- und Ausgabedaten werden über diesen Puffer abgewickelt.

Der Pufferist ein Bereich im Speicher, der für jede Datei zugewiesen wird.

Bei der Aufzeichnung in einer Datei werden alle Informationen zunächst in den Puffer geleitet und sammeln sich dort an, bis das gesamte Volumen des Puffers nicht mehr gefüllt ist. Erst danach oder nach einem speziellen Befehl von dump (z. B. FileClose oder FileFlush). werden die Daten aus dem Puffer in die Datei übertragen.

Beim Lesen aus einer Datei werden die Daten zunächst in den Puffer eingelesen, und es wird nicht so viel gelesen, wie angefordert wird, sondern so viel, wie in den Puffer passt.

Und glauben die Entwickler wirklich, dass dies alles Informationen sind, die für einen Neuling, der MQL studiert, interessant sein können (wenn nur diese Definition für diese Sprache als gültig angesehen werden kann)?

Ich habe mich zum Beispiel gefragt, wie groß dieser Puffer ist und wie er definiert wird.

Meiner Meinung nach sollten alle diese Informationen, und nicht nur diese, in der Sprachdokumentation stehen (dort und nicht in verschiedenen Artikeln und Diskussionen im Forum).

 
Interesting:
OK, ich werde versuchen, selbst eine Referenz zu schreiben
 

Warum gibt das Skript nicht das tatsächliche"Last Read Date" der Datei zurück?

int handle_file;
void OnStart()
  {
   handle_file=FileOpen("Ye_file2.bin",FILE_READ|FILE_WRITE|FILE_BIN);
   switch(handle_file)
     {
      case  INVALID_HANDLE: break;
      default:
         Print("Дата создания файла Ye_file2.bin: ",(datetime)FileGetInteger(handle_file,FILE_CREATE_DATE));
         for(int i=0;i<3;i++)
           {
            Sleep(3000);
            FileReadInteger(handle_file,CHAR_VALUE);
            Print("Дата последнего чтения Ye_file2.bin: ",(datetime)FileGetInteger(handle_file,FILE_ACCESS_DATE));
           }
         FileClose(handle_file);
     }
  }
 
Yedelkin:

Warum gibt das Skript nicht das tatsächliche"Last Read Date" der Datei zurück?

Letzter Zugriff, nicht gelesen. Öffnen Sie den Griff wieder und Sie werden zufrieden sein.
 
TheXpert:
Letzter Zugriff, nicht Lesezugriff.

OK, wie Sie vielleicht bemerkt haben, habe ich in meiner Frage den Satz wörtlich aus der Dokumentation zitiert:

ENUM_FILE_PROPERTY_INTEGER

Kennung

Kennung Beschreibung

FILE_EXISTS

Existenzprüfung

DATEI_ERSTELLEN_DATUM

Datum der Erstellung

FILE_MODIFY_DATE

Datum der letzten Änderung

DATEI_ZUGRIFF_DATUM

Datum des letzten Lesens

Frage 1: Glauben Sie, dass es sich um einen Tippfehler in der Dokumentation handelt und dass statt "Letztes Lesedatum" eher "Letztes Öffnungsdatum" stehen sollte? Aus Ihrer Antwort können Sie zumindest ersehen, dass die Operationen "Datei lesen" und "auf Datei zugreifen" für Sie unterschiedliche Dinge bedeuten.

Weiter. Wenn Sie das angehängte Skript mehrmals neu starten, werden Sie ungefähr das gleiche Verhalten feststellen:

FK      0       FileInteger (EURGBP,M1) 21:33:56        Дата создания файла Ye_file2.bin: 2011.09.03 21:22:25
IP      0       FileInteger (EURGBP,M1) 21:33:59        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:33:57
RL      0       FileInteger (EURGBP,M1) 21:34:02        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:33:57
NH      0       FileInteger (EURGBP,M1) 21:34:06        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:33:57
MH      0       FileInteger (EURGBP,M1) 21:34:43        Дата создания файла Ye_file2.bin: 2011.09.03 21:22:25
EP      0       FileInteger (EURGBP,M1) 21:34:46        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:34:06
 HL      0       FileInteger (EURGBP,M1) 21:34:50        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:34:06
IH      0       FileInteger (EURGBP,M1) 21:34:53        Дата последнего чтения Ye_file2.bin: 2011.09.03 21:34:06

Das heißt, wenn das Skript zum ersten Mal ausgeführt wird, erfolgt der dritte Aufruf vonFileReadInteger() um21:34:06, aber das Datum des letzten Lesezugriffs ist anders -21:33:57.Der zweite Skriptlauf (37 Sekunden später) zeigt jedoch, dass der erste Aufruf der FunktionFileReadInteger() 21 :34:06 ergab , d. h. die Zeit des letzten Aufrufs der FunktionFileReadInteger() während des vorherigen Skriptlaufs.

Außerdem erfolgt der zweite Start des Skripts um 21:34:43 Uhr, was bedeutet, dass das "erneute Öffnen eines Griffs", wie Sie es nennen, zur gleichen Zeit erfolgte. Aber nach einem solchen "Wiederöffnen des Griffs" wird21:34:06 zurückgegeben, d. h. eine völlig andere Zeit als die, von der Sie sprechen.

Frage 2: Wie ist dies zu interpretieren?

TheXpert:
Öffnen Sie den Griff wieder und Sie werden zufrieden sein.

In der gegenwärtigen Situation sind gute Nachrichten zu erwarten, wenn Dateieigenschaften abgerufen werden, ohne den Handle "neu zu öffnen".