Работа с файлами. - страница 2

 
mql5:
строки в MQL юникодные (2 байта на символ), а функции kernel32.dll ансишные (1 байт на символ). Используйте байтовый массив и функцию StringToCharArray для вызова ансишных функций
Как так?
На сколько я припоминаю, винда почти целиком юникодная, причем давно...

Или kernel32.dll - исключение?

-----Добавил------

Посмотрел, действительно анси, странно...

 

Подскажите дилетанту. Познания в работе с файлами - на уровне пользователя Word.

Необходимо на протяжении всего времени работы эксперта перезаписывать в файл одно значение типа  datetime, каждый раз в начало файла. Считывать последнее записанное значение - только при перезагрузке эксперта. Набросал простенькую конструкцию с использованием .csv-файла, - вроде всё работает. Появились такие вопросы:

1)  Какой тип файла лучше использовать для сохранения значений типа  datetime с целью минимизации времени выполнения процедуры записи? Как я понял, .csv-файлы работают со строками, а там, где строки, - там дополнительные затраты времени на их обработку.

2) Как грамотно использовать функцию FileClose(): закрывать  файл каждый раз после записи в него нового значения или же закрыть  файл один раз, в функции  OnDeinit()? Хотелось бы открыть  файл один раз, а потом просто записывать в него новые значения, не тратя время на его многократные открытия-закрытия. Но не опасно ли так делать?

3) Правильно ли я понимаю, что если некоторое значение записано  в файл, но файл не закрыт, то при внезапном отключении питания это записанное значение никуда не денется, и при загрузке программы его можно будет в дальнейшем прочитать?

 

Yedelkin:

Появились такие вопросы:

1)  Какой тип файла лучше использовать для сохранения значений типа  datetime с целью минимизации времени выполнения процедуры записи? Как я понял, .csv-файлы работают со строками, а там, где строки, - там дополнительные затраты времени на их обработку.

2) Как грамотно использовать функцию FileClose(): закрывать  файл каждый раз после записи в него нового значения или же закрыть  файл один раз, в функции  OnDeinit()? Хотелось бы открыть  файл один раз, а потом просто записывать в него новые значения, не тратя время на его многократные открытия-закрытия. Но не опасно ли так делать?

3) Правильно ли я понимаю, что если некоторое значение записано  в файл, но файл не закрыт, то при внезапном отключении питания это записанное значение никуда не денется, и при загрузке программы его можно будет в дальнейшем прочитать?

1. Смотря в каком формате сохранять. Дату можно сохранять как: число, текст или специализированный тип datetime.

Вторым вопросом будет этот - Зачем мы пишем в файл, кто и как его будет просматривать?

Запись в TXT полагаю будет самый простым и надежным вариантом (прочитать можно из любой программы, или почти из любой), CSV - это более совершенный способ записи в файл. Есть свои плюсы, но есть и определены минусы.

2. Я предпочитаю открывать один раз в OnInit или конструкторе основного класса (зависит от реализации), а закрывать в OnDeinit или в деструкторе.

Но если есть необходимость переоткрывать/переоткрывать файл (существует ряд причин таких действий), то можно это делать периодически (разв в час/сутки/неделю).

Если файл большой или информацию в нем трудно будет восстановить то лучше периодически его перезаписывать или создавать новый.

3. Если значение было записано, но файл корректно не закрыт (резкое отключение питания или зависание ПО) скорей всего данные будут потеряны (частично или полностью вопрос отдельный).

Помнится я экспериментировал с записью в обычный txt в программе написанной на Delphi. Так там в случае проблем зачастую была побита или отсутствовала последняя запись.

 

Очень хотелось бы иметь mql-функцию возвращающую время последней модификации файла.

datetime FileLastModificationTime(string FName);
 
MetaDriver:

Очень хотелось бы иметь mql-функцию возвращающую время последней модификации файла.

datetime FileLastModificationTime(string FName); 
Вообще, - мечта поэта!
 
Interesting:

1.  Дату можно сохранять как: число, текст или специализированный тип datetime.

Вот не нашёл функции, сохраняющей дату как тип datetime. Если только через массивы.

Почему-то кажется, что оптимальнее будет сохранять значения типа datetime в бинарный файл (сам файл предназачен только для чтения этим же экспертом при перезагрузке). Попробую поэкспериментировать.

Interesting:

3. Если значение было записано, но файл корректно не закрыт (резкое отключение питания или зависание ПО) скорей всего данные будут потеряны (частично или полностью вопрос отдельный).

Помнится я экспериментировал с записью в обычный txt в программе написанной на Delphi. Так там в случае проблем зачастую была побита или отсутствовала последняя запись.

 Печально. Получается, что если хочешь гарантированно сохранить последнее записанное значение - постоянно используй функцию FileClose()  :(

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

 Печально. Получается, что если хочешь гарантированно сохранить последнее записанное значение - постоянно используй функцию FileClose()  :(

FileFlush()  для этого изобрели.
 

sergeev:

Yedelkin:

 Печально. Получается, что если хочешь гарантированно сохранить последнее записанное значение - постоянно используй функцию FileClose()  :(

FileFlush()  для этого изобрели.

Возможно. Только как ею пользоваться (в каких случаях применять) - ничего не сказано. Может быть для профи это лёгкий вопрос, но лично я после прочтения документации не уловил какого-то особого смысла в FileFlush()...

И разница между FileClose()   и  FileFlush()  до сих пор непонятна :/

 

FileFlush

Сброс на диск всех данных, оставшихся в файловом буфере ввода-вывода.

...Функцию FileFlush() необходимо вызывать между операциями чтения из файла и записи в файл.

 Это что получается, записи в файл ещё нет, а данные уже куда-то "сбрасываются на диск"?

 
Yedelkin:

Возможно. Только как ею пользоваться (в каких случаях применять) - ничего не сказано. Может быть для профи это лёгкий вопрос, но лично я после прочтения документации не уловил какого-то особого смысла в FileFlush()...

И разница между FileClose()   и  FileFlush()  до сих пор непонятна :/

 

 Это что получается, записи в файл ещё нет, а данные уже куда-то "сбрасываются на диск"?

Вот более подробное описание с примером, из справки по MQL4

void FileFlush( int handle)


Сброс на диск всех данных, оставшихся в файловом буфере ввода-вывода.

Замечания: функцию FileFlush() необходимо вызывать между операциями чтения из файла и записи в файл.
При закрытии файла данные сбрасываются на диск автоматически, поэтому нет необходимости вызывать функцию FileFlush() перед вызовом функции FileClose().
Параметры:
handle   -   Файловый описатель, возвращаемый функцией FileOpen().

Пример:

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

Если я все правильно понял то в отличии от FileClose  вызов FileFlush не закрывает файл, что позволяет и дальше работать с файлом. Да и по сравнению с повторным открытием тогда должен получиться существенный прирост по скорости.

Хотя тут нужен более конкретный пример выполнения поставленной задачи.

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

Вот более подробное описание с примером, из справки по MQL4

"При закрытии файла данные сбрасываются на диск автоматически, поэтому нет необходимости вызывать функцию FileFlush() перед вызовом функции FileClose()" - Да-да, начинаю понимать, о чём говорил sergeev. Получается, что для гарантированного сохранения последней записи в файл можно вместо FileClose() вызывать FileFlush()? И это будет грамотным решением?
Причина обращения: