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

 

Моя утилита пишет и обновляет файл.

Работает, однако в какой то момент времени возникает ошибка 5004 (ERR_CANNOT_OPEN_FILE) при FileOpen(file_cpy,FILE_WRITE | FILE_TXT)

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

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

Но если handlе==INVALID_HANDLE, то программа не может его закрыть оператором FileClose(handle);

Можно убрать утилиту с графика и снова присоединить, тогда файл обновляется и утилита работает до следующего сбоя.

Как это можно исправить?

 
Aleksander Gladkov:

Моя утилита пишет и обновляет файл.

Работает, однако в какой то момент времени возникает ошибка 5004 (ERR_CANNOT_OPEN_FILE) при FileOpen(file_cpy,FILE_WRITE | FILE_TXT)

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

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

Но если handlе==INVALID_HANDLE, то программа не может его закрыть оператором FileClose(handle);

Можно убрать утилиту с графика и снова присоединить, тогда файл обновляется и утилита работает до следующего сбоя.

Как это можно исправить?

ищите в коде ситуацию,когда файл не закрывается. Когда  за FileOpen можно не проследовать FileClose

 
Aleksander Gladkov:

Моя утилита пишет и обновляет файл.

Работает, однако в какой то момент времени возникает ошибка 5004 (ERR_CANNOT_OPEN_FILE) при FileOpen(file_cpy,FILE_WRITE | FILE_TXT)

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

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

Но если handlе==INVALID_HANDLE, то программа не может его закрыть оператором FileClose(handle);

Можно убрать утилиту с графика и снова присоединить, тогда файл обновляется и утилита работает до следующего сбоя.

Как это можно исправить?

а так:

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

?
 
Maxim Kuznetsov #:

ищите в коде ситуацию,когда файл не закрывается. Когда  за FileOpen можно не проследовать FileClose

Вы правы, лазейка была.
 
Renat Akhtyamov #:

а так:

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

?

Спасибо, поставил Ваш вариант на запись :

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

и на чтение :

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

В документации написано :

FILE_SHARE_READ Совместный доступ по чтению со стороны нескольких программ. Флаг используется при открытии файлов (FileOpen()), но не заменяет при открытии файла необходимости указать FILE_WRITE и/или флаг FILE_READ


Однако у меня читает и без флага FILE_READ. Посмотрим.

Спасибо за помощь!

 

Казалось, уже все сделано правильно, но нет!

Вот:

Это на домашнем компьютере в России.

Когда я удалил утилиту Get_news5 с графика, а затем снова присоединил, она переписала этот нулевой файл и снова заработала правильно.

Значит дело в ней?

Но она только и делает что открывает, пишет и закрывает, а когда не может открыть ситуация подвисает.

Любопытно, что эти же программы на VPS в это же время не дали никаких ошибок, файл пишется и читается.

 

Процедура следующая:

1. Утилита пишет файл с заданной периодичностью handle=FileOpen(file_cpy,FILE_SHARE_READ|FILE_WRITE|FILE_TXT);

2. Несколько потребителей его читают со своей периодичностью int FileHandle1=FileOpen(file_cpy,FILE_BIN|FILE_SHARE_READ);

Ничего другого не остается как использовать "семафор" в виде глобальной переменной:

Каждый потребитель в момент обращения устанавливает его в 1 а когда закончит обнуляет.

Утилита ждет свободное окно (семафор=0) и только тогда делает попытку открыть файл на запись.

Как Вам такая конструкция?

 
Вполне рабочая
 

Для записи:

// Дозапись в файл
FileOpen(filename,FILE_READ|FILE_WRITE|FILE_SHARE_READ|FILE_TXT)

// Перезапись файла
FileOpen(filename,FILE_WRITE|FILE_SHARE_READ|FILE_TXT)

Для чтения:

FileOpen(filename,FILE_READ|FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_TXT)

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

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

 
Aleksander Gladkov #:

Процедура следующая:

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

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

Ничего другого не остается как использовать "семафор" в виде глобальной переменной:

Каждый потребитель в момент обращения устанавливает его в 1 а когда закончит обнуляет.

Утилита ждет свободное окно (семафор=0) и только тогда делает попытку открыть файл на запись.

Как Вам такая конструкция?

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

 
Aleksander Gladkov #:

Процедура следующая:

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

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

Ничего другого не остается как использовать "семафор" в виде глобальной переменной:

Каждый потребитель в момент обращения устанавливает его в 1 а когда закончит обнуляет.

Утилита ждет свободное окно (семафор=0) и только тогда делает попытку открыть файл на запись.

Как Вам такая конструкция?

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

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

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

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

Документация по MQL5: Работа с базами данных
Документация по MQL5: Работа с базами данных
  • www.mql5.com
Работа с базами данных - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
Причина обращения: