Trabalhar com ficheiros. - página 2

 
mql5:
As strings em MQL são unicode (2 bytes por caracter) e as funções kernel32.dll são ansi (1 byte por caracter). Use uma matriz de bytes e função StringToCharArray para chamar as funções ansish
Como assim?
Se bem me lembro, o Windows é quase inteiramente Unicode, e já o é há muito tempo...

Ou o kernel32.dll é uma excepção?

-----Added------

Olhou para ele, realmente ansioso, estranho...

 

Uma palavra de conselho a um amador. O meu conhecimento de trabalhar com ficheiros está ao nível de um utilizador de Word.

O Consultor Especialista precisa de sobrescrever um valor do tipo de data/hora no ficheiro, cada vez no início do ficheiro, durante todo o tempo do seu trabalho. Leia o último valor escrito - apenas quando reiniciar o Expert Advisor. Fiz uma construção simples, usando um ficheiro .csv - tudo parece funcionar. Surgiram as seguintes questões:

1) Que tipo de ficheiro é melhor utilizar para guardar valores de data e hora a fim de minimizar o tempo do procedimento de escrita? Como entendi, os ficheiros .csv funcionam com cordas, e onde há cordas, há um consumo de tempo adicional para o seu processamento.

2) Como utilizar correctamente FileClose(): devo fechar o ficheiro de cada vez após escrever um novo valor, ou fechá-lo uma vez, na função OnDeinit()? Gostaria de abrir o ficheiro uma vez e depois apenas escrever novos valores nele, sem perder tempo com a abertura - fechando-o várias vezes. Mas será seguro fazê-lo?

3) Compreendo correctamente que se algum valor for escrito no ficheiro, mas o ficheiro não for fechado, então em caso de uma súbita falha de energia este valor escrito não desaparecerá, e quando o programa for carregado, será possível lê-lo mais tarde?

 

Yedelkin:

As seguintes questões foram levantadas:

1) Que tipo de ficheiro é melhor utilizar para guardar valores de data e hora, a fim de minimizar o tempo do procedimento de escrita? Como entendi, os ficheiros .csv funcionam com cordas, e onde há cordas, há um consumo de tempo adicional para o seu processamento.

2) Como utilizar correctamente FileClose(): devo fechar o ficheiro de cada vez após escrever um novo valor, ou fechá-lo uma vez, na função OnDeinit()? Gostaria de abrir o ficheiro uma vez e depois apenas escrever novos valores nele, sem perder tempo com a abertura - fechando-o várias vezes. Mas será seguro fazê-lo?

3) Compreendo correctamente que se algum valor for escrito no ficheiro, mas o ficheiro não for fechado, então em caso de uma súbita falha de energia este valor escrito não desaparecerá, e quando o programa for carregado, será possível lê-lo mais tarde?

1. Depende do formato em que o ficheiro é guardado. A data pode ser guardada como: número, texto ou tipo especial de data/hora.

A segunda questão é a seguinte: porque é que o guardamos num ficheiro, quem o lerá e como é que o verão?

Escrever para TXT seria a opção mais fácil e fiável (pode lê-lo a partir de qualquer programa, ou quase qualquer programa), o CSV é uma forma mais avançada de escrever para ficheiro. Há vantagens, mas há também desvantagens definidas.

2. Prefiro abrir uma vez no OnInit ou construtor da classe principal (depende da implementação) e fechar no OnDeinit ou no destructor.

Mas se houver necessidade de reabrir/reabrir o ficheiro (há várias razões para tais acções), pode fazê-lo periodicamente (uma vez por hora/dia/semana).

Se o ficheiro for grande ou a informação nele contida for difícil de restaurar, é melhor substituí-lo periodicamente ou criar um novo ficheiro.

3. se o valor foi escrito mas o ficheiro não for fechado correctamente (corte de energia repentino ou desligamento do software), muito provavelmente os dados serão perdidos (parcial ou totalmente é uma questão à parte).

Lembro-me de experimentar a escrita para texto simples num programa escrito em Delphi. No caso de problemas, o último registo foi frequentemente batido ou ausente.

 

Uma função mql devolvendo a hora da última modificação do ficheiro seria muito bem-vinda.

datetime FileLastModificationTime(string FName);
 
MetaDriver:

Uma função mql devolvendo a hora da última modificação do ficheiro seria muito bem-vinda.

datetime FileLastModificationTime(string FName); 
Em geral - o sonho de um poeta!
 
Interesting:

1. a data pode ser guardada como: número, texto ou tipo de data/hora especial.

Não consegui encontrar nenhuma função que guarde a data como tipo de data/hora. Se ao menos através de matrizes.

Por alguma razão, parece que seria melhor armazenar valores do tipo data/hora num ficheiro binário (o ficheiro em si foi concebido para ser lido apenas pelo mesmo Expert Advisor durante o recarregamento). Vou tentar experimentar.

Interessante:

Se o valor foi escrito, mas o ficheiro não foi fechado correctamente (corte de energia repentino ou desligamento do software) muito provavelmente os dados serão perdidos (parcial ou completamente é uma questão à parte).

Lembro-me de experimentar a escrita em texto simples num programa escrito em Delphi. Lá, em caso de problemas, o último registo foi frequentemente batido ou desaparecido.

É uma pena. Acontece que se quiser garantir a poupança do último valor deve usar a função FileClose() o tempo todo :(

Документация по MQL5: Основы языка / Типы данных / Целые типы / Тип datetime
Документация по MQL5: Основы языка / Типы данных / Целые типы / Тип datetime
  • www.mql5.com
Основы языка / Типы данных / Целые типы / Тип datetime - Документация по MQL5
 
Yedelkin:

É uma pena. Acontece que, se quiser garantir que o último valor escrito é guardado, tem de utilizar FileClose() a toda a hora :(

FileFlush() foi inventado para este fim.
 

sergeev:

Yedelkin:

É uma pena. Acontece que, se quiser garantir a salvaguarda do último valor que escreveu, tem de utilizar FileClose() a toda a hora :(

FileFlush() foi inventado para este fim.

Pode ser. Mas não diz nada sobre como utilizá-lo (quando utilizá-lo). Pode ser uma pergunta fácil para um profissional, mas pessoalmente não vi nenhum sentido especial em FileFlush() depois de ler a documentação...

E a diferença entre FileClose() e FileFlush() ainda não está clara :/

FileFlush

Repor em disco todos os dados restantes no buffer de E/S do ficheiro.

...FileFlush() deve ser chamado entre operações de leitura e escrita de ficheiros.

Então, não há nenhuma escrita para arquivar e os dados já estão "descarregados em disco" em algum lugar?

 
Yedelkin:

Possivelmente. Mas não diz como utilizá-lo (quando utilizá-lo). Pode ser uma pergunta fácil para um profissional, mas pessoalmente, depois de ler a documentação não vejo nenhum sentido especial em FileFlush()...

E a diferença entre FileClose() e FileFlush() ainda não está clara :/

Então, não há nenhuma escrita no ficheiro, mas os dados já estão "descarregados" em algum lugar?

Aqui está uma descrição mais detalhada e um exemplo da MQL4 Reference

FileFlush nulo( int handle)


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

Nota: FileFlush() deve ser chamado entre operações de leitura e escrita de ficheiros.
Quando um ficheiro é fechado, os dados são automaticamente repostos em disco, pelo que não há necessidade de chamar FileFlush() antes de chamar FileClose().
Parâmetros:
manípulo - Descritor de ficheiro devolvido por FileOpen().

Exemplo:

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

Se bem entendi, a chamada FileFlush, ao contrário de FileClose, não fecha o ficheiro, o que permite continuar a trabalhar com ele. E em comparação com a reabertura, deverá obter um aumento de velocidade significativo.

Embora seja necessário um exemplo mais específico da tarefa em mãos.

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

Aqui está uma descrição mais detalhada com um exemplo, da ajuda da MQL4

"Ao fechar o 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 competente?
Razão: