Как обнаружить файл был усечен во время чтения - PullRequest
3 голосов
/ 15 апреля 2019

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

Я открываю и читаю файлы нативными методами Python:

file = open(self.file_path, 'r')
# ... later
line = file.readline()

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

Однако некоторые файлы журнала не удаляются.Вместо этого они усекаются, и новый контент записывается в начало того же файла.

У меня проблемы с надежным определением того, когда это произошло, поскольку pyinotify просто сообщит только о записи.Единственное доказательство, которое я сейчас получаю, это то, что pyinotify сообщает о записи, а readline() возвращает пустую строку.НО, возможно, что две последующие записи могут вызывать одинаковое поведение.

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

Есть ли простой способ обнаружить, что файл был обрезан при чтении с него?


Редактировать:

* 1021Усечение файла может быть смоделировано с помощью простых команд оболочки:
echo hello > test.log
echo hello >> test.log
# Truncate test.log
echo goodbye > test.log

Чтобы дополнить это, можно использовать простой скрипт на python, чтобы подтвердить, что file.tell() не уменьшается при усечении файла:

foo = open('./test.log', 'r')
line = foo.readline()
while line != '':
    print(foo.tell())
    print(line)
    line = foo.readline()

# Put a breakpoint on the following line and 
# truncate the file before it executes
print(foo.tell())

1 Ответ

1 голос
/ 15 апреля 2019

Используйте os.lseek(file.fileno(),0,os.SEEK_CUR) для получения байтового смещения без перемещения указателя файла. Вы действительно не можете использовать обычный файловый интерфейс, чтобы выяснить это, не в последнюю очередь потому, что он может иметь буферизованный текст (которого больше нет), который он еще не сделал видимым для Python. Если файл не является потоком байтов (, например, , значение по умолчанию open в Python 3), он может даже находиться в середине многобайтового символа и не сможет продолжить работу, даже если файл немедленно вырос после вашего смещения файла.

...