C ++: открытие файла в неисключительном режиме - PullRequest
4 голосов
/ 26 августа 2008

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

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

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

Ответы [ 5 ]

3 голосов
/ 26 августа 2008

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

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

это кроссплатформенный?

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

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

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

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

1 голос
/ 26 августа 2008

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

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

1 голос
/ 26 августа 2008

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

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

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

РЕДАКТИРОВАТЬ: Просто краткая заметка о комментарии Грег Хьюгилл. Я только что проверил с материалом FILE_SHARE * (тоже будьте уверены на 100%). Кроме того, можно удалять и переименовывать файлы в окнах, если открыть только для чтения и указать параметры FILE_SHARE *.

1 голос
/ 26 августа 2008

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

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

0 голосов
/ 16 сентября 2008

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

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