Будет ли Python открывать файл до того, как он закончит запись? - PullRequest
3 голосов
/ 02 июня 2011

Я пишу скрипт, который будет опрашивать каталог в поисках новых файлов.

В этом сценарии необходимо ли выполнять какую-либо проверку ошибок, чтобы убедиться, что файлы полностью записаны перед тем, как получить к ним доступ?

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

Это то, о чем я должен беспокоиться, или файл будет заблокирован, потому что операционная система записывает данные на жесткий диск?

Это в системе Linux.

Ответы [ 4 ]

6 голосов
/ 02 июня 2011

Как правило, в Linux, если вы не используете какую-либо блокировку, два процесса вполне могут одновременно открыть один и тот же файл, даже для записи. Есть три способа избежать проблем с этим:

  1. Замок

    Если писатель применяет блокировку к файлу, можно предотвратить частичное чтение читателем файла. Тем не менее, большинство блокировок являются рекомендательными, поэтому все равно можно увидеть частичные результаты. (Обязательные блокировки существуют, но настоятельно рекомендуется , а не на том основании, что они слишком хрупкие.) Правильный код блокировки написать довольно сложно, и делегировать такие задачи в специализированную библиотеку нормально ( т. е. движку базы данных!) В частности, вы не хотите использовать блокировку в сетевых файловых системах; это источник колоссальных проблем, когда он работает и часто может пойти не так.

  2. * * Конвенция 1015

    Вместо этого можно создать файл в том же каталоге с другим именем, которое вы не будете автоматически искать на стороне чтения (например, .foobar.txt.tmp), и затем атомно переименовать в правильное имя (например, foobar.txt) как только письмо закончено. Это может работать довольно хорошо, если вы позаботитесь о том, чтобы при предыдущих запусках не удалось правильно записать файл. Если за один раз должен быть только один писатель, это довольно просто реализовать.

  3. Не беспокойтесь об этом

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

В Python нет ничего особенного. Все программы, работающие в Linux, имеют одинаковые проблемы.

3 голосов
/ 02 июня 2011

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

Читатель, конечно, должен быть готов к работе с неполным файлом (учитывая, что на стороне автора может происходить буферизация ввода / вывода).

Если это не стартер, вам нужно подумать о какой-то схеме синхронизации писателя и читателя, например:

  • явно заблокировать файл;
  • записать данные во временное местоположение и переместить их на конечное место только после завершения файла (операция перемещения может быть выполнена атомарно, при условии, что и источник, и место назначения находятся в одной файловой системе).
0 голосов
/ 03 июня 2011

Да, будет.

Я предпочитаю «соглашение об именовании файлов» и решение по переименованию, описанное Доналом.

0 голосов
/ 02 июня 2011

Если у вас есть некоторый контроль над пишущей программой, попросите ее записать файл в другое место (например, в каталог / tmp) и затем, когда это будет сделано, переместить его в каталог, за которым вы следите.

Если у вас нет контроля над программой, выполняющей запись (и под «контролем» я имею в виду «редактировать исходный код»), вы, вероятно, не сможете заставить ее также выполнять блокировку файлов, так что, вероятно, из. В этом случае вам, вероятно, понадобится что-то узнать о формате файла, чтобы узнать, когда завершится запись. Например, если писатель всегда пишет «ГОТОВО» в качестве последних четырех символов в файле, вы можете открыть файл, выполнить поиск до конца и прочитать последние четыре символа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...