Arbeiten mit Dateien. - Seite 3

 
Yedelkin:
"Wenn Sie eine Datei schließen, werden die Daten automatisch auf die Festplatte übertragen, so dass es nicht notwendig ist, FileFlush() vor dem Aufruf von FileClose() aufzurufen" - Ja, ja, ich beginne zu verstehen, wasSergejew meinte. Es stellt sich also heraus, dass Sie anstelle von FileClose() FileFlush() aufrufen können, um die Speicherung des letzten Datensatzes in der Datei zu gewährleisten? Und das soll eine intelligente Lösung sein?

nicht anstelle von, sondern durch die Notwendigkeit.

Flush - setzt die verbleibenden Daten zurück und schließt die Datei NICHT. Das ist es doch, was Sie wollen, oder?

Schließen - setzt den Rest der Daten auf die Festplatte zurück und schließt.

 
sergeev:

nicht anstelle von, sondern durch die Notwendigkeit.

Flush - setzt die verbleibenden Daten zurück und schließt die Datei NICHT. Das ist es doch, was Sie wollen, oder?

Schließen - löscht die verbleibenden Daten auf die Festplatte und schließt das Programm.

Ja, das ist genau das, worüber wir sprechen. Danke für den Hinweis auf eine intelligente Lösung!
 
Yedelkin:

Etwas über Zeitminimierung mit FileFlush() funktioniert nicht sehr gut:

2011.05.29 21:58:20 FlushSave (EURGBP,M1) FileFlush. GetTickCount() = 133766
2011.05.29 22:00:33 FlushSave (EURGBP,M1) FileClose. GetTickCount() = 133734
Es dauert sogar gleich lange, bis beide Funktionen funktionieren.

So wie ich es verstanden habe, verschiebt diese Zeile die Position ohne Versatz an den Anfang der Datei. Auf diese Weise können vorhandene Informationen überschrieben werden (d. h. das Datum wird aktualisiert, aber nicht in der Datei gespeichert).

FileSeek(handle_file,0,SEEK_SET);

Durch die Verwendung von move to end of file anstelle von SEEK_SET würden sich die Daten in der Datei stapeln.

 
Yedelkin:

Bei jedem Flush öffnen Sie ein neues Dateihandle. Und wozu? Und man schließt sie übrigens nicht.

Der Vorteil der FileFlush-Funktion ist, dass Sie den Handle nicht erneut öffnen müssen.

Документация по MQL5: Файловые операции / FileFlush
Документация по MQL5: Файловые операции / FileFlush
  • www.mql5.com
Файловые операции / FileFlush - Документация по MQL5
 
Interesting:

1. So wie ich es verstehe, verschiebt diese Zeile die Position in der Datei ohne Versatz. Dadurch können vorhandene Informationen überschrieben werden (d.h. das Datum wird aktualisiert, aber nicht in der Datei gespeichert).

Wenn also anstelle von SEEK_SET skip to the end of file verwendet wird, werden die Daten in der Datei gesammelt.
Ich hatte bereits Zeit, meine Nachricht zu löschen. Dort im Beispiel eingefügt FileFlush() nach dem Schreiben in die Datei.
 
TheXpert:

Bei jedem Flush öffnen Sie ein neues Dateihandle. Und wozu? Und Sie schließen sie übrigens nicht.

Der Vorteil der FileFlush-Funktion ist, dass Sie den Handle nicht erneut öffnen müssen.

Ich habe es so gemacht:

int handle_file;
datetime t;
uint u;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---пример с функцией FileFlush()
   u=GetTickCount();
   handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);
//for(int i=0;i<100000;i++)
   for(int i=0;i<1000;i++)
     {
      if(handle_file!=INVALID_HANDLE)
        {
         t=TimeLocal();
         FileSeek(handle_file,0,SEEK_SET);
         FileFlush(handle_file);
         FileWrite(handle_file,t);
        }
     }
   FileClose(handle_file);
   Print("FileFlush. GetTickCount() = ",GetTickCount()-u);

//---пример без функции FileFlush()
   u=GetTickCount();
   for(int i=0;i<1000;i++)
     {
      handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);
      if(handle_file!=INVALID_HANDLE)
        {
         t=TimeLocal();
         FileSeek(handle_file,0,SEEK_SET);
         FileWrite(handle_file,t);
         FileClose(handle_file);
        }
     }
   Print("FileClose. GetTickCount() = ",GetTickCount()-u);
  }

Ergebnis:

2011.05.29 23:14:31 FlushSave (EURGBP,M1) FileFlush. GetTickCount() = 13563
2011.05.29 23:14:32 FlushSave (EURGBP,M1) FileClose. GetTickCount() = 531

Die Leitungen wurden gemäß der Dokumentation vertauscht:

         FileFlush(handle_file);
         FileWrite(handle_file,t);
Aber ich verstehe nicht, warum man FileFlush() vor FileWrite() aufruft.
 
Yedelkin:

Ich habe es so gemacht:

Ergebnis:

2011.05.29 23:14:31 FlushSave (EURGBP,M1) FileFlush. GetTickCount() = 13563
2011.05.29 23:14:32 FlushSave (EURGBP,M1) FileClose. GetTickCount() = 531

Ich habe die Leitungen gemäß der Dokumentation vertauscht:

Der Sinn des Aufrufs von FileFlush() vor FileWrite() muss jedoch noch verstanden werden.

Hier ist die Variante:

int handle_file;
datetime t;
uint u;

void OnStart()
{
//---пример с функцией FileFlush()
u=GetTickCount();

handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);

  for(int i=0;i<1000;i++)
  {
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileFlush(handle_file);
    FileWrite(handle_file,t);
    }
  }

FileClose(handle_file);

Print("FileFlush. GetTickCount() = ",GetTickCount()-u);

}

Das Ergebnis ist FileFlush. GetTickCount() = 26125

Hier ist die Variante:

int handle_file;
datetime t;
uint u;

void OnStart()
{
//---пример без функции FileFlush()
u=GetTickCount();

  for(int i=0;i<1000;i++)
  {
  handle_file=FileOpen("Ye_file2.txt",FILE_READ|FILE_WRITE|FILE_TXT);
      
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileWrite(handle_file,t);
    FileClose(handle_file);
    }

  }

Print("FileClose. GetTickCount() = ",GetTickCount()-u);

}
Das Ergebnis ist FileClose. GetTickCount() = 3969
 

Diese Option ergab ein Ergebnis zwischen 47 und 110

int handle_file;
datetime t;
uint u;

void OnStart()
{

u=GetTickCount();

handle_file=FileOpen("Ye_file.txt",FILE_READ|FILE_WRITE|FILE_TXT);

  for(int i=0;i<1000;i++)
  {
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileWrite(handle_file,t);
    }
  }

FileClose(handle_file);

Print("FileFlush. GetTickCount() = ",GetTickCount()-u);

}

1. Schlussfolgerung - Die Verwendung von FileFlush in einer Schleife verlangsamt die Ausführung um etwa 260 Mal.

2. Eine Schleife für 50.000 Datensätze in dieser Variante hat folgendes Ergebnis - FileFlush. GetTickCount() = 1891.

3. Ich habe es versäumt, das Terminal zu beenden, als ich den 50000-Schreibzyklus ausgeführt habe, ohne die Datei zu beenden (ich habe das Terminal geschlossen und den Prozess "beendet").

4. Ich konnte das Terminal mit einer 100000er Schleife beenden, und die Datei enthielt mehr als 65536 Datensätze (so viel Platz in Excel 2003).

 
Yedelkin:

Ich habe die Leitungen gemäß der Dokumentation vertauscht:

Wo steht das in der Dokumentation?

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

Wie kann man etwas, das keinen hat, sinnvoll nutzen? Geben Sie die Reihenfolge der Zeichenketten zurück und überprüfen Sie sie erneut. Offensichtlich wurde dies in der Dokumentation nicht korrekt ausgedrückt.

Aber... Dank Ihrer Tests scheint der Fehler entdeckt worden zu sein - FileFlush scheint übermäßig viel Zeit zu verbrauchen, wenn keine Änderungen vorgenommen werden.

Interessant:

OMG! Es ist dort, wo die Schlussfolgerung lautet, dass es ein Morast ist. So entstehen Aussagen wie "OOP ist schneller" oder "Indikatoren sind langsam, wir sollten den gesamten Code in den Expert Advisor verlagern".

 
papaklass:

Experte, schreiben Sie auf, wie Sie diese Funktion richtig nutzen.

Rein hypothetisch:

// open handle
for(int i=0;i<1000;i++)
  {
    if(handle_file!=INVALID_HANDLE)
    {
    t=TimeLocal();
    FileSeek(handle_file,0,SEEK_END);
    FileWrite(handle_file,t);
    FileFlush(handle_file);
    }
  }
// close handle

D.h. es ist richtig, das Bündel FileClose - FileOpen mit FileFlush zu vergleichen.

Theoretisch sollte FileFlush ein Teil von FileClose sein und könnte nicht langsamer sein als das Bundle.

Es hat keinen Sinn, Veränderungen zu spülen, bevor sie auftreten, denn sie sind noch nicht da :)

Aber trotz der wilden Schlussfolgerungen sind die Tests indikativ, also warten wir auf Kommentare von Entwicklern, wie die Funktion funktioniert, wenn es keine Änderungen gibt.