Каталоги раскладки: как не перехватывать файлы, которые все еще пишутся? - PullRequest
6 голосов
/ 29 сентября 2011

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

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

Мой тестовый пример довольно прост.Я копирую и вставляю 300 МБ файлов в каталог раскладки, и часто сценарий захватывает файл, который все еще пишется.Он работает только с частичным файлом, затем удаляет его.Это вызывает ошибку файловой операции в ОС, поскольку файл, в который он записывал, исчезает.

  • Я пытался получить блокировку файла (используя модуль FileLock) перед открытием/ обработать / удалить его.Но это не помогло.

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

Мой тест проводится на OSX, но я пытаюсь найти решение, которое будет работать на основных платформах.

Я вижу похожеевопрос здесь ( Как проверить, что файл все еще пишется? ), но не было четкого решения.

Спасибо

Ответы [ 5 ]

2 голосов
/ 29 сентября 2011

В качестве обходного пути вы можете прослушивать измененные в файле события ( watchdog является кроссплатформенным). Измененное событие (по крайней мере в OS X) не запускается для каждой записи, оно запускается только при закрытии. Поэтому, когда вы обнаружите измененное событие, вы можете предположить, что все записи завершены.

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

1 голос
/ 29 сентября 2011

У каждой ОС будет свое решение, потому что механизмы блокировки файлов не переносимы.

  • В Windows вы можете использовать блокировку ОС.
  • В Linux вы можете просмотреть открытые файлы (аналогично тому, как это делает lsof), и если файл открыт, оставьте его.
1 голос
/ 29 сентября 2011

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

1 голос
/ 29 сентября 2011

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

0 голосов
/ 29 сентября 2011

Вы пытались открыть файл перед копированием?Если файл все еще используется, open () должен выдать исключение.

try:
  with open(filename, "rb") as fp:
    pass
  # Copy the file
except IOError:
  # Dont copy
...