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





Эксклюзивный режим требует не операция чтения, а переименование, потому что это по сути то же самое, что перемещение файла в новое место.
Я не уверен, но не думаю, что это можно сделать. Вместо этого попробуйте скопировать файл, а позже удалите / замените старый файл, когда он больше не читается.
Семантика файловой системы Win32 требует, чтобы переименованный файл не был открыт (в любом режиме) во время переименования. Вам нужно будет закрыть файл, переименовать его, а затем создать новый файл журнала.
Семантика файловой системы Unix позволяет вам переименовывать открытый файл, потому что имя файла является просто указателем на индексный дескриптор.
Если вы читаете только из файла, я знаю, что это можно сделать с помощью Windows API CreateFile. Просто укажите FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE в качестве входных данных для dwShareMode.
К сожалению, это не кроссплатформенный. Но что-то подобное может быть и для Linux.
См. Msdn для получения дополнительной информации о CreateFile..
Обновлено: Просто небольшое примечание о комментарии Грега Хьюгилла. Я только что протестировал материал FILE_SHARE * (тоже будьте уверены на 100%). И есть возможность как удалять, так и переименовывать файлы в окнах, если вы открываете только для чтения и указываете параметры FILE_SHARE *.
Is there a way to open file in a non-exclusive way,
Да, используя Win32, передавая различные флаги FILE_SHARE_Xxxx в CreateFile.
is it cross platform?
Нет, для этого требуется код, зависящий от платформы.
Из-за раздражающих проблем обратной совместимости (приложения DOS, будучи однозадачными, предполагают, что ничто не может удалить файл из-под них, то есть они могут fclose (), а затем fopen () без каких-либо сбоев; Win16 сохранил это предположение, чтобы сделать легче переносить приложения DOS, Win32 сохранил это предположение, чтобы упростить перенос приложений Win16, и это ужасно), по умолчанию Windows открывает только файлы.
Базовая инфраструктура ОС поддерживает удаление / переименование открытых файлов (хотя я считаю, что у нее есть ограничение, что файлы с отображением памяти не могут быть удалены, что, я думаю, не является ограничением, обнаруженным в * nix), но семантика открытия по умолчанию - нет.
C++ не имеет ни малейшего представления об этом; Операционная среда C++ во многом такая же, как и операционная среда DOS - другие приложения не работают одновременно, поэтому нет необходимости контролировать совместное использование файлов.
Я бы позаботился о том, чтобы вы не оставляли файлы открытыми. Это приводит к странным вещам, например, если ваше приложение вылетает из строя. Что бы я сделал: