Trabalhar com ficheiros. - página 4

 

TheXpert:

OMG! Onde a saída é, é um disparate. É assim que obtemos as alegações como "OOP é mais rápido" ou "os indicadores são lentos, devemos colocar o código inteiro no Expert Advisor".

Compreendo que tudo não funciona como planeado. Pelo menos, o uso normal de FileFlush() deve ser mais rápido do que FileClose().

Mas continuo a pensar que tais coisas não devem ser colocadas em laços; de qualquer modo, não serão de grande ajuda.

E se entendi correctamente o exemplo para MQL4, a chamada deFileFlush() é colocada entre dois loops (sugeriu-me que seria um travão num loop).

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

Assim, se eu entender correctamente a lógica dos criadores, o ficheiro deve ser aberto no OnInit / Construtor da classe principal (talvez não só no construtor) e fechado no OnDeint / Destrutivo da classe principal.

Emtodos os outros casos em vez de FileClose use FileFlush (depois de FileWrite e depois de loops).


 

TheXpert:

Yedelkin:

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

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

Onde é que isto está escrito na documentação?

Existe uma frase deste tipo na MQL5 Reference:

FileFlush

Nota

A função FileFlush() deve ser chamada entre operações de leitura de um ficheiro e escrita para um ficheiro.

Se "escrever para ficheiro" == Função FileWrite(), então leia: "A função FileFlush() deve ser chamada antes da função FileWrite() ".Ou tem uma opinião diferente?

TheXpert:

Yedelkin:
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 linhas à página inicial e verificar duas vezes. Aparentemente, a documentação não o pôs muito bem.

É bom quando se sabe com antecedência o que faz sentido e o que não faz quando se estuda material novo. Uma vez que a natureza não nos dotou de tais talentos, temos de "tomar cada nova altura", testar, interpretar documentação e resultados. Nem sequer tenho a certeza de que os testes em si estejam escritos correctamente. No início coloquei intuitivamente FileFlush() após FileWrite(), mas depois de reler o Manual, apaguei esse exemplo.

TheXpert:

Interessante:

OMG! É absurdo onde está a produção. É assim que obtemos as alegações como "OOP é mais rápido" ou "os indicadores são lentos, devemos colocar o código inteiro no Expert Advisor".

Seria bom que cada avaliação da "sua produção é estúpida" fosse seguida pela explicação do que é estúpido nela :) Caso contrário, não é claro em que direcção avançar inquisitivamente com tanto rigor da magistratura :)

 
TheXpert:

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

Não vai acreditar, mas exactamente por esta razão escrevi "Mas não compreendo o sentido de chamar FileFlush() antes de FileWrite()", referindo-me à documentação anterior. Mas não tenho coragem e conhecimentos suficientes para questionar todas as linhas da documentação :)
... Bem, o curso é claro - estamos à espera do que os programadores dirão se algum problema for realmente detectado.
 
Yedelkin:

Existe uma frase deste tipo na MQL5 Reference:

Se "write to file" == função FileWrite(), lê-se "A função FileFlush() deve ser chamada antes da função FileWrite() ".Ou tem uma opinião diferente?

Vamos analisar a descrição "bastante infeliz" e o exemplo desta função para a MQL4.

FileFlush nulo( int handle)


Reinicia para disco todos os dados restantes no buffer de E/S do ficheiro.

Nota: A função FileFlush() deve ser chamada entre operações de leitura e escrita de ficheiros.
Quando o ficheiro é fechado, os dados são automaticamente descarregados no disco, pelo que não há necessidade de chamar FileFlush() antes de chamar FileClose().

A linha aqui marcada é o argumento da necessidade de colocar FileFlush call no laço antes de escrever no ficheiro.

Mas se compreendermos este comentário palavra por palavra, teremos o seguinte:

a função FileFlush() deve ser chamada entre as operações de leitura do ficheiro (enquanto a leitura é FileReadXXX) e a escrita no ficheiro (a escrita está ligada a FileWrite e FileWriteXXX).

Ao fechar o ficheiro (ler - quando FileClose é executado), os dados são despejados no disco automaticamente (ler - quando FileFlush é executado automaticamente).


Penso que os programadores não se preocuparam muito com a correcção da leitura da ajuda mesmo na versão MQL4; é até ridículo falar em colocar a parte truncada na MQL5.

Pelo menos a segunda frase do comentário acima deve, na minha opinião, ter a seguinte redacção:

Os dados são automaticamente repostos em disco quando o ficheiro éfechado, pelo que não há necessidade de chamar FileFlush() antes de chamar FileClose().

Também é um pouco confuso, mas de algum ponto de vista explica porque é que FileFlush não deve ser usado antes de fechar o ficheiro usando FileClose.


O exemplo não é tão simples, o texto diz sobre uma coisa (utilização entre operações de leitura e escrita), enquanto que o exemplo descreve a utilização entre duas operações de escrita em loop (o trabalho dentro de loops, a propósito, não é de todo considerado como ajuda).

Assim, no mínimo, deve ser acrescentado o seguinte:

1. uma descrição do que é este buffer de entrada/saída e o que realmente acontece nele entre abrir um ficheiro, ler um bloco de dados, escrever um bloco de dados e fechar o ficheiro.

Isto refere-se muito provavelmente a toda a secção sobre operações de arquivo.

2. Dar um exemplo normalmente compreendido (pode ser baseado em classes) de como utilizar correctamente a chamada FileFlush para acesso a um único ficheiro (por exemplo, valor do temporizador de escrita).

3 Fornecer um exemplo normal de uma chamada quando se trabalha com matrizes. Tanto quanto sei, o exemplo descrito na Referência MQL4 refere-se ao trabalho com matrizes grandes, mas ilustra-o incorrectamente (numa palavra - porquê escrever duas vezes uma quantidade bastante grande de dados idênticos ao ficheiro, se pode ser feito várias vezes?)

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

A linha aqui destacada é o seu argumento para a necessidade de chamar FileFlush no laço antes de escrever para o ficheiro.

Mas se compreendermos este comentário palavra por palavra, obtemos o seguinte:

a função FileFlush() deve ser chamada entre as operações de leitura do ficheiro (enquanto a leitura é FileReadXXX) e a escrita no ficheiro (a escrita está ligada a FileWrite e FileWriteXXX).

Ao fechar o ficheiro (ler - ao executar FileClose), os dados serão automaticamente descarregados para o disco (ler - ao executar FileFlush).

Estou a ver o que quer dizer. Lamento, mas sem saber, equiparava a operação "ler do ficheiro" à função FileOpen() (o meu Expert Advisor lerá apenas do OnInit(), enquanto durante o processamento de carraças e eventos personalizados - apenas escrever; por esta razão não considerei funções como FileReadXXX() no laço). No entanto, FileFlush() antes de FileWriteXXX() - o princípio é o mesmo em ambas as referências. E não foi argumentação no seu significado clássico (como raciocínio da minha posição), mas simplesmente uma resposta à pergunta porque fiz essa frase.

De qualquer modo, se os criadores não responderem aqui, publicarei um pedido esta noite, com um link para a discussão e resultados intermédios. Até duas aplicações são necessárias: 1) "bug - não um bug" e 2) alterações na documentação. Gostaria de fazer você mesmo a segunda aplicação, uma vez que já se aprofundou tanto no tema?

 
Yedelkin:

Estou a ver o que estou a pensar. Confesso, que sem saber, equiparava a operação "ler do ficheiro" à função FileOpen() (o meu Expert Advisor lerá apenas do OnInit(), enquanto durante o processamento de ticks e eventos do utilizador - apenas escrever; por esta razão não considerei funções como FileReadXXX() no laço). No entanto, FileFlush() antes de FileWriteXXX() - o princípio é o mesmo em ambas as referências. E não foi argumentação no seu significado clássico (como raciocínio da minha posição), mas simplesmente uma resposta à pergunta porque fiz essa frase.

De qualquer modo, se os criadores não responderem aqui, escreverei um pedido esta noite, com um link para a discussão e resultados intermédios. Até duas aplicações são necessárias: 1) "bug - não um bug" e 2) alterações na documentação. Gostaria de fazer você mesmo o segundo pedido, uma vez que se debruçou tão profundamente sobre o assunto?

1. Será tão profundo? provavelmente teria muito gosto em fazê-lo, se entendesse o que os criadores querem dizer e onde.

Por vezes há uma menção de um tampão de E/S, mas não há uma descrição adequada do mesmo. Ou será que todos aqui sabem o que é o tampão de E/S do FILE?

É difícil acrescentar uma descrição normal desta questão no capítulo sobre operações de arquivo? Ou procurar no Google em todo o mundo à procura de uma resposta para o que os criadores tinham em mente?

Compreendo que o tamanho da ajuda é limitado, mas porque devemos gozar com aqueles que estão apenas a começar a aprender MQL?

2. Porquê qualquer menção a este tampão que encontrei apenas na Ajuda para esta função, porque não é mencionado noutra parte da secção sobre operações de ficheiros?

3. vamos supor que tenho alguma ideia deste mesmo buffer de entrada/saída aproximadamente nesta forma

A noção de buffer input-output está ligada ao sistema de ficheiros. Os dados de entrada e saída são efectuados através deste buffer.

Bufferé uma área na memória que é atribuída para cada ficheiro.

Num ficheiro, todas as informações são inicialmente dirigidas ao tampão e acumulam-se até que todo o volume do tampão não seja preenchido. Só depois disso ou após um comando especial de despejo (por exemplo, FileClose ou FileFlush). os dados são transferidos do buffer para o ficheiro.

Ao ler a partir de um ficheiro, os dados são lidos pela primeira vez no buffer, e não tantos dados são lidos como são pedidos, mas tantos quanto cabem no buffer.

E os criadores pensam realmente que tudo isto é informação que pode ser interessante para um recém-chegado que estuda MQL (se apenas esta definição puder ser considerada válida para esta língua)?

Por exemplo, estava a pensar qual é o tamanho deste amortecedor e como é definido.

Na minha opinião, toda esta informação, e não só, deveria estar na documentação linguística (lá, e não em vários artigos e discussões sobre o fórum).

 
Interesting:
OK, eu próprio tentarei escrever uma referência
 

Porque é que o guião não devolve a"Data da última leitura" real do ficheiro?

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:

Porque é que o guião não devolve a"Data da última leitura" real do ficheiro?

Último acesso, não lido. Reabra a pega e ficarás feliz.
 
TheXpert:
Último acesso, acesso não lido.

OK, como deve ter notado, na minha pergunta citei a frase textualmente da documentação:

ENUM_FILE_PROPERTY_INTEGER

Identificador

Descrição do identificador

FILE_EXISTAS

Verificação de existência

FILE_CREATE_DATE

Data de criação

FILE_MODIFY_DATE

Data da última modificação

FILE_ACCESS_DATE

Data da última leitura

Pergunta 1: Acha que existe uma gralha na documentação, e que em vez de "Last Read Date" deveria ser algo como "Last Open Date"? Pelo menos a partir da sua resposta, pode ver que as operações "ler ficheiro" e "ficheiro de acesso" significam coisas diferentes para si.

Além disso. Se reiniciar o guião anexado várias vezes, verá aproximadamente o mesmo comportamento:

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

Ou seja, ao executar o guião pela primeira vez, a terceira chamada paraFileReadInteger() tem lugar às21:34:06, mas a data da última leitura/acesso é diferente -21:33:57.Contudo, o segundo script executado (37 segundos depois) mostra que a primeira chamada da funçãoFileReadInteger() resultou em 21 :34:06, ou seja, a hora da última chamada da funçãoFileReadInteger() durante a execução do script anterior.

Além disso, o segundo lançamento do guião às 21:34:43 ocorre, o que significa que a "reabertura de uma pega", como lhe chamam, ocorreu ao mesmo tempo. Mas depois de uma tal "reabertura do cabo" regressa21:34:06, ou seja, um tempo completamente diferente do que se está a falar.

Pergunta 2: como deve isto ser interpretado?

TheXpert:
Reabra a pega e ficarás feliz.

Na situação actual, esperam-se boas notícias quando as propriedades do ficheiro são recuperadas sem "reabrir" a pega.

Razão: