Скачать MetaTrader 5

Чтение из файла на каждом тике

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Опубликуй статью. Получи вознаграждение!
Evgeny Potapov
1632
Evgeny Potapov 2016.11.03 12:04 

Здравствуйте!

Индикатор пишет в файл, а советник должен читать (использование стандартных буферов не обсуждается)

Но почему-то советник прочитывает всегда один и тот же текст, хотя индикатор на каждом тике пишет новый и использует    FileFlush(FileHandle);
Вот так открывается файл в советнике:

FileHandle = FileOpen(FileName, FILE_TXT|FILE_SHARE_READ|FILE_READ |FILE_WRITE|FILE_SHARE_WRITE);

Вот так открывается файл в индикаторе:

   FileHandle = FileOpen(FileName, FILE_TXT|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ);

Вот как идёт чтение в советнике:

   // FileFlush(FileHandle);
   Sleep(10);
   FileSeek(FileHandle, SEEK_SET, 0);
   for(int i=0; i<howManyLines; i++) {
      string l = FileReadString(FileHandle);

...

Почему может прочитываться один и тот же текст на каждом тике, если в файле текст меняется (я проверял)

Dmitry Fedoseev
42912
Dmitry Fedoseev 2016.11.03 14:26  
Evgeny Potapov:

...(использование стандартных буферов не обсуждается)...

Почему?
new-rena
3372
new-rena 2016.11.03 17:00  
Evgeny Potapov:

Здравствуйте!

Индикатор пишет в файл, а советник должен читать (использование стандартных буферов не обсуждается)

Но почему-то советник прочитывает всегда один и тот же текст, хотя индикатор на каждом тике пишет новый и использует    FileFlush(FileHandle);
Вот так открывается файл в советнике:

FileHandle = FileOpen(FileName, FILE_TXT|FILE_SHARE_READ|FILE_READ |FILE_WRITE|FILE_SHARE_WRITE);

Вот так открывается файл в индикаторе:

   FileHandle = FileOpen(FileName, FILE_TXT|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ);

Вот как идёт чтение в советнике:

   // FileFlush(FileHandle);
   Sleep(10);
   FileSeek(FileHandle, SEEK_SET, 0);
   for(int i=0; i<howManyLines; i++) {
      string l = FileReadString(FileHandle);

...

Почему может прочитываться один и тот же текст на каждом тике, если в файле текст меняется (я проверял)

Файлик после чтения закрываете?

И попробуйте закомментить FileSeek

И вот это лучше уж так: FileHandle = FileOpen(FileName, FILE_TXT|FILE_SHARE_READ|FILE_SHARE_WRITE);

И коль индикатор только читает, то лучше так: FileOpen(FileName, FILE_TXT|FILE_SHARE_READ);

После прочтения нужно:

FileClose(FileHandle);
Что позволит открыть и прочитать в следующий раз уже изменённый файл
Evgeny Potapov
1632
Evgeny Potapov 2016.11.04 04:38  
new-rena:

Файлик после чтения закрываете?

И попробуйте закомментить FileSeek

И вот это лучше уж так: FileHandle = FileOpen(FileName, FILE_TXT|FILE_SHARE_READ|FILE_SHARE_WRITE);

И коль индикатор только читает, то лучше так: FileOpen(FileName, FILE_TXT|FILE_SHARE_READ);

После прочтения нужно:

FileClose(FileHandle);
Что позволит открыть и прочитать в следующий раз уже изменённый файл

FILE_TXT|FILE_SHARE_READ - даёт ошибку 5004 - (cannot open file)


Открытие, закрытие файлов довольно таки дорогая по времени операция. Хотелось бы, чтобы процесс шёл максимально быстро. То есть по сути я хочу образовать трубку.

Не найдётся ли у вас реально работающего примера трубки?

new-rena
3372
new-rena 2016.11.04 05:25  
Evgeny Potapov:

1) FILE_TXT|FILE_SHARE_READ - даёт ошибку 5004 - (cannot open file)


2) Открытие, закрытие файлов довольно таки дорогая по времени операция. Хотелось бы, чтобы процесс шёл максимально быстро. То есть по сути я хочу образовать трубку.

Не найдётся ли у вас реально работающего примера трубки?

1) Уже ближе к теме выявления проблемы. Разбирайтесь тогда - почему не открывается файл. Команда должна работать без ошибки.

Подозреваю, что у Вас советник также не закрывает файл после его модификации. Не закрытый файл уже не открыть индикатором.

В советник пишем такое:

FileHandle = FileOpen(FileName, FILE_TXT|FILE_SHARE_READ|FILE_SHARE_WRITE);

2) шлюз?  неее, такое не дам, хотя и есть. Пишите сами:

https://www.mql5.com/ru/forum/95692#comment_2824688

Экспорт котиров в порт или файл из МТ5
Экспорт котиров в порт или файл из МТ5
  • www.mql5.com
Задача,научить tslab торговать по реальным тиковым котировкам,которые можно получить из мт5 по определенному финансовому инструменту...
Vladimir
329
Vladimir 2016.11.04 19:39  
Evgeny Potapov:Открытие, закрытие файлов довольно таки дорогая по времени операция. Хотелось бы, чтобы процесс шёл максимально быстро.

Если требуется максимальное быстродействие, то зачем использовать индикатор. Он ведь работает в интерфейсном потоке, то есть ждет перерисовку всех видимых окон терминала, а это чаще всего миллисекунды, а то и десятки миллисекунд. Тогда как обмен между памятью и файловыми буферами операционной системы занимает микросекунды, если передается несколько сот байт данных. Также как и сброс содержимого этих буферов в буферы контроллера жесткого диска, который и считается самой затратной по времени частью операции закрытия файла, расположенного на жестком диске. О том, что открытие файла занимает какое-то заметное время, не слышал.

Еще мне вспоминается, что Ренат Фатхуллин сообщал о том, что после очередного увеличения быстродействия файловых операций функция FileFlush в большинстве случаев стала ничего не делать. Однако в документации это не отражено, может быть, сейчас снова что-нибудь делает всегда или почти всегда. В тот момент я проверил, закрыть и снова открыть файл оказалось весьма быстро, и перестал вообще использовать FileFlush. Возможно, его сообщение относилось только к MQL4, но я на всякий случай так поступил в программах на обоих языках, MQL4 и MQL5.

Mislaid
622
Mislaid 2016.11.04 23:08  
При частой записи и совместном доступе на чтение/запись возникает проблема: мы должны удостовериться, что мы прочитали корректную информацию. У меня есть один такой индикатор. Количество неверно прочитанных файлов существенно. Самое простое решение из далеких годов. Индикатор считает контрольную сумму записываемой информации и помещает ее в конец файла. Тот, кто читает, по тому же алгоритму считает контрольную сумму. Если контрольные суммы совпадают, тогда считаем, что файл был прочитан верно.
new-rena
3372
new-rena 2016.11.05 00:40  

У человека проблема описана в 1-ом посте.

Очевидно, что файл читается советником только первый раз, когда индикатор его еще не занял для записи.

Поэтому в индикаторе надо файл закрыть после модификации. Если файл не закрывать, то изменения возможно советник не заметит.

Далее - на второй раз советник уже получает ошибку открытия файла. Соответственно - файл опять же по просту не закрыт индикатором

Далее, команда FileFlush в конечном итоге погубит жесткий диск. Поэтому не советую.

Итак, файл нужно открывать в советнике так:

FileHandle = FileOpen(FileName, FILE_TXT|FILE_READ);

а в индикаторе так:

FileHandle = FileOpen(FileName, FILE_TXT|FILE_READ|FILE_WRITE);

И в конце, в обоих случаях закрыть

FileClose(FileHandle);

Поскольку файл каждый раз закрывается, то скорее всего контрольная сумма не понадобится. Просто нужно проверить, будет ли возвращать "true"  FileOpen(). Ну и функция обработки ошибок нужна будет.

Вот тогда будет надежно.

//я там повыше думал что советник изменяет файл. прошу прощения

Mislaid
622
Mislaid 2016.11.05 06:31  
Evgeny Potapov:


Почему может прочитываться один и тот же текст на каждом тике, если в файле текст меняется (я проверял)

Чтение/запись происходит в буфер. Поэтому данные не меняются.

new-rena правильно пишет, что файлы нужно закрывать.

Правильно было написать FileSeek(FileHandle, 0, SEEK_SET); 

но, поскольку  SEEK_SET = 0, то фактически ошибки нет.

Mislaid
622
Mislaid 2016.11.05 06:55  
new-rena:

У человека проблема описана в 1-ом посте.

Очевидно, что файл читается советником только первый раз, когда индикатор его еще не занял для записи.

Поэтому в индикаторе надо файл закрыть после модификации. Если файл не закрывать, то изменения возможно советник не заметит.

Далее - на второй раз советник уже получает ошибку открытия файла. Соответственно - файл опять же по просту не закрыт индикатором

Далее, команда FileFlush в конечном итоге погубит жесткий диск. Поэтому не советую.

Итак, файл нужно открывать в советнике так:

FileHandle = FileOpen(FileName, FILE_TXT|FILE_READ);

а в индикаторе так:

FileHandle = FileOpen(FileName, FILE_TXT|FILE_READ|FILE_WRITE);

И в конце, в обоих случаях закрыть

FileClose(FileHandle);

Поскольку файл каждый раз закрывается, то скорее всего контрольная сумма не понадобится. Просто нужно проверить, будет ли возвращать "true"  FileOpen(). Ну и функция обработки ошибок нужна будет.

Вот тогда будет надежно.

//я там повыше думал что советник изменяет файл. прошу прощения

Все так. Я  считаю, что в советниках можно открыть совместный доступ на чтение.

С контрольной суммой чисто моя заморочка. Она возникла из необходимости открыть совместный доступ на чтение в советнике и в индикаторе. То есть, когда открыт совместный доступ в индикаторе и в советниках, возникает проблема корректности прочитанных данных. Меня это вынудил сделать Excel. Он падает с критической ошибкой, если файл кем-то открыт, а к нему нет совместного доступа.

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий