Поведение записи по умолчанию-O_TRUNC или O_APPEND?

Поведение записи по умолчанию-O_TRUNC или O_APPEND?

23.01.2020 11:25:45 Просмотров 25 Источник

Каково поведение по умолчанию при openфайла в режиме доступа O_WRONLYили O_RDWR. Файл открыт в режиме добавления или усечения? Из мужских страниц:

Флаги аргументов должны включать один из следующих режимов доступа: O_RDONLY, O_WRONLY или O_RDWR.
...
Кроме того, ноль или более флагов создания файлов и флагов состояния файлов могут быть побитовыми или в виде флагов.

Это звучит так, как будто O_APPENDи O_TRUNCнеобязательны. Итак, что же делает следующее?

void main ( void )
{
    int fd = open( "foo.txt", O_WRONLY );

    write( fd, "hello", 5 );

    close( fd );
}
У вопроса есть решение - Посмотреть?

Ответы - Поведение записи по умолчанию-O_TRUNC или O_APPEND? / Default write behaviour - O_TRUNC or O_APPEND?

Является ответом!
John Kugelman

23.01.2020 11:34:40

Ни.

  • По умолчанию файл открывается курсором, расположенным в начале строки. Запись перезаписывает байты в начале файла.

  • O_TRUNCвызывает усечение файла, если он существует.

  • O_APPENDприводит к тому, что записи добавляются в конец файла вместо перезаписи в начале. Этот флаг является постоянным. При перемещении курсора в другое место для чтения данных он всегда перемещается в конец файла перед каждой записью.

Флаги ортогональны и не являются взаимоисключающими. Вы даже можете объединить их, если вы хотите изначально усечь файл и убедиться, что все последующие записи всегда добавляются.

https://stackoverflow.com/questions/59886546/default-write-behaviour-o-trunc-or-o-append/59886657#comment105903648_59886657
Обратите внимание на POSIX, вы можете использовать pwrite() для записи в любом месте в файле, даже если он открыт с O_APPEND: "в pwrite() функция должна быть эквивалентна write(), за исключением того, что он пишет в данной позиции и не меняет смещение файла (независимо от того, O_APPEND имеет значение)."Это позволяет файлу, открытому с O_APPEND, либо атомарно добавлять данные, либо атомарно записывать их с произвольным смещением. К сожалению, pwrite()в Linux не работает
https://stackoverflow.com/questions/59886546/default-write-behaviour-o-trunc-or-o-append/59886657#comment105905042_59886657
@AndrewHenle: Спасибо, что напомнили! Я был зол на эту ошибку WONTFIX с тех пор, как впервые услышал о ней, и теперь, когда есть pwritev2syscall с аргументом flags, я думаю, что это, наконец, исправимо без нарушения стабильности API ядра. Непроверенный патч для добавления опции, которую функция userspace pwrite может передать, чтобы исправить это: ix.io/28aG
dbush

23.01.2020 11:46:35

При использовании флага O_WRONLYон сам открывает файл для записи, сохраняет существующее содержимое файла и помещает указатель файла в начало файла. Любая запись перезаписывает существующий контент.

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

Это поведение контрастирует с O_TRUNC, который усекает содержимое файла при открытии, и с O_APPEND, который заставляет все записи происходить в конце файла.

Закрыть X