Travailler avec des fichiers. - page 3

 
Yedelkin:
"Lorsque vous fermez un fichier, les données sont vidées sur le disque automatiquement, il n'est donc pas nécessaire d'appeler FileFlush() avant d'appeler FileClose()" - Oui, oui, je commence à voir de quoisergeev parlait. Il s'avère donc qu'au lieu de FileClose(), vous pouvez appeler FileFlush() pour garantir la sauvegarde du dernier enregistrement dans le fichier ? Et ce serait une solution intelligente ?

non pas à la place, mais par nécessité.

Flush - réinitialise les données restantes, et ne ferme PAS le fichier. C'est ce que tu veux, non ?

Fermer - réinitialise le reste des données sur le disque et ferme.

 
sergeev:

non pas à la place, mais par nécessité.

Flush - réinitialise les données restantes, et ne ferme PAS le fichier. C'est ce que tu veux, non ?

Fermer - vide les données restantes sur le disque et ferme.

Oui, c'est exactement ce dont il s'agit. Merci pour l'astuce d'une solution intelligente !
 
Yedelkin:

Quelque chose sur la minimisation du temps en utilisant FileFlush() ne fonctionne pas très bien :

2011.05.29 21:58:20 FlushSave (EURGBP,M1) FileFlush. GetTickCount() = 133766
2011.05.29 22:00:33 FlushSave (EURGBP,M1) FileClose. GetTickCount() = 133734
En fait, il faut le même temps pour que les deux fonctions fonctionnent.

Si j'ai bien compris, cette ligne déplace la position au début du fichier sans décalage. Cela permet d'écraser les informations existantes (c'est-à-dire que la date est mise à jour, mais elle ne s'accumule pas dans le fichier).

FileSeek(handle_file,0,SEEK_SET);

En utilisant move to end of file au lieu de SEEK_SET, les données s'empilent dans le fichier.

 
Yedelkin:

Vous ouvrez un nouveau gestionnaire de fichier à chaque fois que vous effectuez un vidage. Pour quoi faire ? Et vous ne le fermez pas, d'ailleurs.

L'avantage de la fonction FileFlush est que vous n'avez pas besoin de rouvrir la poignée.

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

1. Si je comprends bien, cette ligne déplace la position dans le fichier sans décalage. Cela permet d'écraser les informations existantes (c'est-à-dire que la date est mise à jour mais ne s'accumule pas dans le fichier).

Ainsi, si elle est utilisée à la place de SEEK_SET skip à la fin du fichier, les données seront accumulées dans le fichier.
J'ai déjà eu le temps de supprimer mon message. Dans l'exemple, on insère FileFlush() après avoir écrit dans le fichier.
 
TheXpert:

Vous ouvrez un nouveau gestionnaire de fichier à chaque fois que vous effectuez un vidage. Pour quoi faire ? Et vous ne le fermez pas, d'ailleurs.

L'avantage de la fonction FileFlush est que vous n'avez pas besoin de rouvrir la poignée.

Je l'ai fait comme ça :

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

Résultat :

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

J'ai échangé les lignes, selon la documentation :

         FileFlush(handle_file);
         FileWrite(handle_file,t);
Mais je ne comprends pas l'intérêt d'appeler FileFlush() avant FileWrite().
 
Yedelkin:

Je l'ai fait comme ça :

Résultat :

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

J'ai interverti les lignes, selon la documentation :

Mais l'intérêt d'appeler FileFlush() avant FileWrite() reste à comprendre.

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

}

Le résultat est FileFlush. GetTickCount() = 26125

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

}
Le résultat est FileClose. GetTickCount() = 3969
 

Cette option a donné un résultat compris entre 47 et 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. Conclusion - L'utilisation de FileFlush dans une boucle ralentit l'exécution d'environ 260 fois.

2. Une boucle pour 50 000 enregistrements dans cette variante donne le résultat suivant - FileFlush. GetTickCount() = 1891.

3. Je n'ai pas réussi à tuer le terminal lors de l'exécution du cycle de 50000 écritures sans quitter le fichier (j'ai fermé le terminal et "tué" le processus).

4. J'ai pu tuer le terminal avec une boucle de 100000, et le fichier contenait plus de 65536 enregistrements (autant d'espace dans Excel 2003).

 
Yedelkin:

J'ai interverti les lignes en suivant la documentation :

Où est-ce que cela est indiqué dans la documentation ?

Mais je ne comprends toujours pas le sens de l'appel de FileFlush() avant FileWrite().

Comment pouvez-vous donner un sens à quelque chose qui n'en a pas ? Retournez l'ordre des chaînes et vérifiez-le à nouveau. Apparemment, la documentation ne l'a pas exprimé correctement.

Mais... Grâce à vos tests, le bogue semble avoir été détecté - FileFlush semble prendre un temps excessif lorsqu'aucune modification n'est apportée.

Intéressant:

OMG ! C'est là où l'on déduit que c'est un marasme. C'est ainsi qu'apparaissent des affirmations telles que "la POO est plus rapide" ou "les indicateurs sont lents, nous devrions déplacer l'ensemble du code vers le conseiller expert".

 
papaklass:

Expert, écrivez comment utiliser correctement cette fonction.

Hypothétiquement, oui :

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

C'est-à-dire qu'il est correct de comparer FileClose -- FileOpen bundle avec FileFlush.

Théoriquement, FileFlush devrait faire partie de FileClose et ne pourrait pas être plus lent que le paquet.

Il n'y a aucun intérêt à supprimer les changements avant qu'ils n'apparaissent, car ils ne sont pas encore là :)

Mais, malgré les conclusions sauvages, les tests sont indicatifs, donc nous attendons les commentaires des développeurs sur le fonctionnement de la fonction lorsqu'il n'y a pas de changement.

Raison: