Как удалить или исправить файл после ошибки 5004 ? - страница 2

 
Alexey Viktorov #:

И на сколько эта периодичность отличается друг от друга? Не может случиться так, что прочёл один, обнулил GV и утилита увидев 0, не дожидаясь следующего читателя перезапишет этот файл…

Вы правы, работать не будет
 
Maxim Kuznetsov #:

может лучше базу использовать ? https://www.mql5.com/ru/docs/database

один писатель, много читателей, гарантирована целостность в транзакциях..

заодно история будет сохраняться

опциональная оптимизация: в глоб.переменную вывести просто время последней записи. Тогда читатель всегда может сверится и если время поменялось уже лезть в базу а не постоянно периодично читать.

Вот база (сервер, не файл) нужна как раз когда писателей несколько.

 
Aleksander Gladkov #:
Вы правы, работать не будет

А на сколько важно, чтобы прочли все читатели до перезаписи файла?

Потом возникает резонный вопрос, а если один из читателей «туповат» и долго читает, а другому уже нужна новая информация из этого файла?

Много нюансов. Все их учесть можете только вы, зная их…

 
JRandomTrader #:

Вот база (сервер, не файл) нужна как раз когда писателей несколько.

SQLite может подглючивать/протормаживать на многих писателях. У него файловые блокировки. Тогда лучше сразу выбирать другую базу

А вот когда писатель один, читателей много, данные взаимосвязаны и нужна целостность - милое дело

 
JRandomTrader #:

Для записи:

Для чтения:

Т.е., указывая FILE_SHARE_X разрешаем другим открывать этот файл для X (но вот если несколько хотят открыть для записи - тут уже между ними нужна явная синхронизация).

Эти "другие" тоже должны открывать его с тем же FILE_SHARE_X, иначе не смогут.

У меня:

1. Утилита пишет файл с заданной периодичностью

handle=FileOpen(file_cpy,FILE_SHARE_READ|FILE_WRITE|FILE_TXT);

2. Несколько потребителей его читают со своей периодичностью

int FileHandle1=FileOpen(file_cpy,FILE_BIN|FILE_SHARE_READ);

Нужно ли для чтения добавить: FILE_SHARE_WRITE ? И тогда для записи тоже?

Я умышленно для чтения не поставил FILE_READ, считая что в этом случае потребитель захватит файл и не даст другим его открывать что и приводило к ошибке.

 

У меня сейчас Lua-скрипт из Квика пишет инфу в файл, а несколько роботов в MT5 читают.

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

 
Aleksander Gladkov #:

У меня:

1. Утилита пишет файл с заданной периодичностью

handle=FileOpen(file_cpy,FILE_SHARE_READ|FILE_WRITE|FILE_TXT);

2. Несколько потребителей его читают со своей периодичностью

int FileHandle1=FileOpen(file_cpy,FILE_BIN|FILE_SHARE_READ);

Нужно ли для чтения добавить: FILE_SHARE_WRITE ? И тогда для записи тоже?

Я умышленно для чтения не поставил FILE_READ, считая что в этом случае потребитель захватит файл и не даст другим его открывать что и приводило к ошибке.

Неправильно. FILE_READ - это просто открытие для чтения.

Указывая читателю FILE_SHARE_READ, мы разрешаем другим открывать его по READ при условии, что и этот другой разрешает нам его читать (указывает FILE_SHARE_READ).

Указывая FILE_SHARE_WRITE, мы разрешаем другим в файл писать (открывать по FILE_WRITE), опять же, если эти другие не против, чтобы мы этот файл читали (указывают FILE_SHARE_READ).

 
Aleksander Gladkov #:

У меня:

1. Утилита пишет файл с заданной периодичностью

handle=FileOpen(file_cpy,FILE_SHARE_READ|FILE_WRITE|FILE_TXT);

2. Несколько потребителей его читают со своей периодичностью

int FileHandle1=FileOpen(file_cpy,FILE_BIN|FILE_SHARE_READ);

Нужно ли для чтения добавить: FILE_SHARE_WRITE ? И тогда для записи тоже?

Я умышленно для чтения не поставил FILE_READ, считая что в этом случае потребитель захватит файл и не даст другим его открывать что и приводило к ошибке.

FILE_READ и FILE_SHARE_READ это разные ключи. Ключ  FILE_READ всё-же нужен, чтобы не зависеть от умолчания. А ключ FILE_SHARE_READ только разрешает другим читателям этот файл использовать для чтения.

Ключ FILE_SHARE_WRITE позволит писателю перезаписать файл даже в тот момент когда файл читается…

 
Maxim Kuznetsov #:

может лучше базу использовать ? https://www.mql5.com/ru/docs/database

один писатель, много читателей, гарантирована целостность в транзакциях..

заодно история будет сохраняться

опциональная оптимизация: в глоб.переменную вывести просто время последней записи. Тогда читатель всегда может сверится и если время поменялось уже лезть в базу а не постоянно периодично читать.

Меня заинтересовала возможность:

DATABASE_OPEN_MEMORY

Создать базу данных в оперативной памяти

 

А как построить взаимодействие с базой нескольких программ?

//--- создадим имя файла
   string filename=IntegerToString(AccountInfoInteger(ACCOUNT_LOGIN))+"_trades.sqlite";
//--- открываем/создаем базу данных в общей папке терминалов
   int db=DatabaseOpen(filenameDATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
   if(db==INVALID_HANDLE)
     {
      Print("DB: "filename" open failed with code "GetLastError());
      return;
     }

Организационно получается все аналогично работе с файлом.

И, возможно, с теми же проблемами.

 
Rashid Umarov #:
Вполне рабочая
А как избежать коллизий?
Причина обращения: