Trabalhar com ficheiros. - página 3

 
Yedelkin:
"Quando se fecha um ficheiro, os dados são automaticamente repostos em disco, pelo que não há necessidade de chamar FileFlush() antes de chamar FileClose()" - Sim, sim, estou a começar a ver do que é queSergeev estava a falar. Então, acontece que em vez de FileClose() pode chamar FileFlush() para garantir a gravação do último registo no ficheiro? E esta seria uma solução inteligente?

não em vez de, mas por necessidade.

Flush - reinicia os dados restantes, e NÃO fecha o ficheiro. É isto que pretende, certo?

Fechar - repõe o resto dos dados em disco e fecha.

 
sergeev:

não em vez de, mas por necessidade.

Flush - reinicia os dados restantes, e NÃO fecha o ficheiro. É isto que pretende, certo?

Fechar - descarrega os dados restantes para o disco e fecha.

Sim, é exactamente disso que estamos a falar. Obrigado pela dica sobre uma solução inteligente!
 
Yedelkin:

Algo sobre a minimização do tempo usando FileFlush() não funciona muito bem:

2011.05.29 21:58:20 FlushSave (EURGBP,M1) FileFlush. GetTickCount() = 133766
2011.05.29 22:00:33 FlushSave (EURGBP,M1) FileClose. GetTickCount() = 133734
De facto, é necessário o mesmo tempo para que ambas as funções funcionem.

Como entendi, esta linha move a posição para o início do ficheiro sem compensação. Isto permite sobrescrever a informação existente (isto é, a data é actualizada, mas não se acumula no ficheiro).

FileSeek(handle_file,0,SEEK_SET);

Ao utilizar mover para o fim do ficheiro em vez de SEEK_SET, os dados acumular-se-iam no ficheiro.

 
Yedelkin:

Abre-se uma nova pega de ficheiro cada vez que se puxa o autoclismo. Para quê? E, a propósito, não se fecha.

A vantagem da função FileFlush é que não é necessário reabrir a pega.

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

1. Pelo que entendi, esta linha move a posição no ficheiro sem compensação. Isto permite que a informação existente seja substituída (ou seja, a data é actualizada mas não se acumula no ficheiro)

Assim, se usado em vez de SEEK_SET saltar para o fim do ficheiro, os dados serão acumulados no ficheiro.
Já tive tempo de apagar a minha mensagem. Aí no exemplo inserido FileFlush() depois de escrever no ficheiro.
 
TheXpert:

Abre-se uma nova pega de ficheiro cada vez que se puxa o autoclismo. Para quê? E, a propósito, não se fecha.

A vantagem da função FileFlush é que não é necessário reabrir a pega.

Fi-lo desta forma:

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

Resultado:

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

Trocou as linhas, de acordo com a documentação:

         FileFlush(handle_file);
         FileWrite(handle_file,t);
Mas não compreendo o objectivo de chamar FileFlush() antes de FileWrite().
 
Yedelkin:

Fi-lo desta forma:

Resultado:

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

Troquei as linhas, de acordo com a documentação:

Mas o ponto de chamar FileFlush() antes de FileWrite() ainda tem de ser compreendido.

Aqui está a 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);

}

O resultado é FileFlush. GetTickCount() = 26125

Aqui está a 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);

}
O resultado é FileClose. GetTickCount() = 3969
 

Esta opção deu um resultado entre 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. Conclusão - A utilização de FileFlush num loop atrasa a execução em cerca de 260 vezes.

2. Um laço para 50.000 registos nesta variante tem o seguinte resultado - FileFlush. GetTickCount() = 1891.

3. Não consegui matar o terminal ao executar o ciclo de escrita de 50000 sem sair do ficheiro (fechei o terminal e "matei" o processo).

4. Consegui matar terminal com 100000 laço, e o ficheiro continha mais de 65536 registos (tanto espaço no Excel 2003).

 
Yedelkin:

Troquei as linhas de acordo com a documentação:

Onde diz isso na documentação?

Mas ainda não compreendo o sentido de chamar FileFlush() antes de FileWrite().

Como se pode dar sentido a algo que não tem um? Devolver a ordem das cordas e verificá-la duas vezes. Aparentemente, a documentação não o exprimia correctamente.

Mas... Graças aos seus testes, o bug parece ter sido detectado - FileFlush parece consumir uma quantidade desmesurada de tempo quando não são feitas alterações.

Interessante:

OMG! É onde se deduz que se trata de um pântano. É assim que afirmações como "OOP é mais rápido" ou "os indicadores são lentos, devemos mover todo o código para o Expert Advisor".

 
papaklass:

Perito, anote como utilizar correctamente esta função.

Hipoteticamente, sim:

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

Ou seja, é correcto comparar FileClose -- Pacote FileOpen com FileFlush.

Teoricamente, FileFlush deveria fazer parte de FileClose e não poderia ser mais lento do que o pacote.

Não vale a pena descarregar as alterações antes de elas aparecerem porque ainda não estão lá :)

Mas, apesar das conclusões selvagens, os testes são indicativos, pelo que aguardamos comentários dos criadores sobre o funcionamento da função quando não há alterações.