Lavorare con i file. - pagina 3

 
Yedelkin:
"Quando si chiude un file, i dati vengono scaricati su disco automaticamente, quindi non c'è bisogno di chiamare FileFlush() prima di chiamare FileClose()" - Sì, sì, comincio a capire di cosa stava parlandosergeev. Quindi, si scopre che invece di FileClose() si può chiamare FileFlush() per garantire il salvataggio dell'ultimo record nel file? E questa sarebbe una soluzione intelligente?

non al posto di, ma per necessità.

Flush - azzera i dati rimanenti e NON chiude il file. Questo è quello che vuoi, giusto?

Close- resetta il resto dei dati sul disco e chiude.

 
sergeev:

non al posto di, ma per necessità.

Flush - azzera i dati rimanenti e NON chiude il file. Questo è quello che vuoi, giusto?

Close - scarica i dati rimanenti sul disco e chiude.

Sì, è esattamente quello di cui stiamo parlando. Grazie per il suggerimento di una soluzione intelligente!
 
Yedelkin:

Qualcosa sulla minimizzazione del tempo usando FileFlush() non funziona molto bene:

2011.05.29 21:58:20 FlushSave (EURGBP,M1) FileFlush. GetTickCount() = 133766
2011.05.29 22:00:33 FlushSave (EURGBP,M1) FileClose. GetTickCount() = 133734
In effetti, ci vuole la stessa quantità di tempo perché entrambe le funzioni funzionino.

Come ho capito questa linea sposta la posizione all'inizio del file senza offset. Questo permette di sovrascrivere le informazioni esistenti (cioè la data viene aggiornata, ma non si accumula nel file).

FileSeek(handle_file,0,SEEK_SET);

Usando move to end of file invece di SEEK_SET, i dati si accumulerebbero nel file.

 
Yedelkin:

Si apre un nuovo handle di file ogni volta che si esegue il flush. Per quale motivo? E comunque non si chiude.

Il vantaggio della funzione FileFlush è che non è necessario riaprire l'handle.

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

1. Da quanto ho capito, questa linea sposta la posizione nel file senza offset. Questo permette di sovrascrivere le informazioni esistenti (cioè la data viene aggiornata ma non si accumula nel file)

Così, se usato al posto di SEEK_SET salta alla fine del file, i dati saranno accumulati nel file.
Ha già avuto il tempo di cancellare il mio messaggio. Lì nell'esempio inserito FileFlush() dopo aver scritto sul file.
 
TheXpert:

Si apre un nuovo handle di file ogni volta che si esegue il flush. Per quale motivo? E comunque non si chiude.

Il vantaggio della funzione FileFlush è che non è necessario riaprire l'handle.

Ho fatto così:

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

Risultato:

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

Ho scambiato le linee, secondo la documentazione:

         FileFlush(handle_file);
         FileWrite(handle_file,t);
Ma non capisco il senso di chiamare FileFlush() prima di FileWrite().
 
Yedelkin:

Ho fatto così:

Risultato:

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

Ho scambiato le linee, secondo la documentazione:

Ma il senso di chiamare FileFlush() prima di FileWrite() deve ancora essere compreso.

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

}

Il risultato è FileFlush. GetTickCount() = 26125

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

}
Il risultato è FileClose. GetTickCount() = 3969
 

Questa opzione ha dato un risultato tra 47 e 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. Conclusione - Utilizzare FileFlush in un ciclo rallenta l'esecuzione di circa 260 volte.

2. Un ciclo per 50.000 record in questa variante ha il seguente risultato: FileFlush. GetTickCount() = 1891.

3. Non sono riuscito a uccidere il terminale durante l'esecuzione del ciclo di 50000 scritture senza uscire dal file (ho chiuso il terminale e "ucciso" il processo).

4. Sono stato in grado di uccidere il terminale con 100000 loop, e il file conteneva più di 65536 record (tanto spazio in Excel 2003).

 
Yedelkin:

Ho scambiato le linee secondo la documentazione:

Dove lo dice nella documentazione?

Ma ancora non capisco il senso di chiamare FileFlush() prima di FileWrite().

Come si può dare un senso a qualcosa che non ne ha uno? Restituisce l'ordine delle stringhe e lo ricontrolla. A quanto pare la documentazione non l'ha espresso correttamente.

Ma... Grazie ai vostri test, il bug sembra essere stato individuato - FileFlush sembra consumare una quantità spropositata di tempo quando non vengono fatte modifiche.

Interessante:

OMG! È dove si deduce che è un pantano. È così che appaiono affermazioni come "OOP è più veloce" o "gli indicatori sono lenti, dovremmo spostare l'intero codice nell'Expert Advisor".

 
papaklass:

Esperto, scrivi come usare correttamente questa funzione.

Ipoteticamente sì:

// 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

Cioè è corretto confrontare FileClose -- FileOpen bundle con FileFlush.

Teoricamente, FileFlush dovrebbe essere una parte di FileClose e non potrebbe essere più lento del bundle.

Non ha senso sciacquare i cambiamenti prima che appaiano, perché non ci sono ancora :)

Ma, nonostante le conclusioni selvagge, i test sono indicativi, quindi aspettiamo i commenti degli sviluppatori su come funziona la funzione quando non ci sono cambiamenti.