Каталоги раскладки: как не раскладки файлов, которые все еще пишутся?


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

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

Мой тестовый случай довольно прост. Я копирую-вставляю 300 МБ файлов в каталог pickup, и часто скрипт захватывает файл, который все еще пишется. Он работает только с частичным файлом, а затем удаляет его. Это запускает ошибка работы файла в операционной системе, так как файл, в который он записывался, исчез.
  • Я попытался получить блокировку файла (используя модуль FileLock), прежде чем открыть/обработать/удалить его. Но это не помогло.

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

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

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

Спасибо

5 6

5 ответов:

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

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

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

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

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

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

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

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