Сведения о вопросе

Mathprofi

22:45, 21st August, 2020

Теги

c++   windows   linux   filesystems    

C++: открытие файла в неисключительном режиме

Просмотров: 472   Ответов: 5

Я должен разработать приложение, которое анализирует файл журнала и отправляет определенные данные на сервер. Он должен работать как на Linux, так и на Windows.

Проблема возникает, когда я хочу протестировать систему роллинга журналов (которая добавляет .1 к имени создаваемого нового с тем же именем). На Windows (еще не протестирован на Linux) я не могу переименовать файл, который я открыл с помощью std::ifstream () (эксклюзивный доступ?) даже если я открою его в "input mode" (ios::in).

Существует ли кросс-платформенный способ открыть файл неисключительным способом?



  Сведения об ответе

ITSME

22:31, 20th August, 2020

Есть ли способ, чтобы открыть файл в режиме нон-эксклюзивный способ,

Да, используя Win32, передавая различные флаги FILE_SHARE_Xxxx в CreateFile.

это кросс-платформа?

Нет, для этого требуется специфичный для платформы код.

Из-за раздражающих проблем обратной совместимости (DOS приложений, будучи однозадачными, предполагают, что ничто не может удалить файл из-под них, т. е. что они могут fclose(), а затем fopen() без каких-либо проблем; Win16 сохранил это предположение, чтобы сделать перенос DOS приложений проще, Win32 сохранил это предположение, чтобы сделать перенос Win16 приложений проще, и это ужасно), Windows по умолчанию открывает исключительно файлы.

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

C++ не имеет ни малейшего понятия об этом; операционная среда C++ во многом совпадает с операционной средой DOS-никаких других приложений, работающих одновременно, поэтому нет необходимости контролировать общий доступ к файлам.


  Сведения об ответе

KOMP

04:59, 14th August, 2020

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

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


  Сведения об ответе

ASER

02:50, 21st August, 2020

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

Unix семантика файловой системы позволяет переименовать открытый файл, поскольку имя файла является всего лишь указателем на индекс.


  Сведения об ответе

piter

00:53, 25th August, 2020

Если Вы читаете только из файла, я знаю, что это можно сделать с windows api CreateFile. Просто укажите FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE в качестве входных данных для dwShareMode.

К сожалению, это не кроссплатформа. Но что-то подобное может быть и для Linux.

Смотрите msdn для получения дополнительной информации о CreateFile .

EDIT: только быстрое примечание о Грег Hewgill комментарий. Я только что проверил с вещами FILE_SHARE* (тоже будьте 100% уверены). И можно как удалять, так и переименовывать файлы в windows, если открыть только для чтения и указать параметры FILE_SHARE*.


  Сведения об ответе

appple

23:44, 2nd August, 2020

Я бы проследил, чтобы ты не держал файлы открытыми. Это приводит к странным вещам, например, если ваше приложение аварийно завершает работу. Что бы я сделал:

  1. Аннотация (чтение / запись / переход к новому файлу) в один класс и организовать закрытие файла, когда вы хотите перейти к новому файлу в этом классе. (это самый аккуратный способ, и поскольку у вас уже есть код ролл-овер, вы уже на полпути туда.)
  2. Если у вас должно быть несколько точек доступа для чтения/записи, вам нужны все функции fstreams и вы не хотите писать эту полную оболочку, то единственное кросс-платформенное решение, которое я могу придумать,-это всегда закрывать файл, когда он вам не нужен, и иметь код ролл-овера, который пытается получить эксклюзивный доступ к файлу несколько раз, когда ему нужно свернуть, прежде чем сдаться.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться