Python-как проверить, используется ли файл другим приложением?

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

есть ли подходящие для Python способ сделать это? В противном случае, как я могу достичь этого в Unix и Windows?

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

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

Я понимаю, что это, вероятно, зависит от ОС, поэтому сейчас это может быть не связано с python.

3 ответов


будет ли ваш скрипт python желать открыть файл для записи или для чтения? Является ли устаревшее приложение открытием и закрытием файла между записями или сохраняет его открытым?

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

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


обновление

Итак, зная (из вашего комментария), что:

устаревшие приложения и закрытие файла каждые X минут, но Я не хочу предполагать, что при t = t_0 + n*X + eps он уже закрыт папка.

параметры задачи изменяются. На самом деле это может быть сделано независимым от ОС способом с учетом нескольких предположений или как комбинация зависимых от ОС и независимых от ОС методов. :)

  1. OS-независимый способ: если можно с уверенностью предположить, что устаревшее приложение сохраняет файл открытым в течение не более некоторого известного количества времени, скажем T секунд (например, открывает файл, выполняет одну запись, затем закрывает файл), и повторно открывает его более или менее каждый X секунд, где X больше, чем 2*T.
    • stat файл
    • вычесть время изменения файла из now(), поддавшись D
    • если T D X затем откройте файл и сделайте с ним то, что вам нужно
    • это может быть достаточно безопасно для вашего приложения. Безопасность увеличивается как T/X уменьшается. На * nix у вас может быть перепроверить /etc/ntpd.conf для правильной конфигурации time-stepping vs. slew (см. tinker). Для Windows см. в MSDN
  2. окна: кроме того (или вместо) метода, независимого от ОС, вы можете попытаться использовать либо:
    • общий доступ (блокировка): это предполагает, что устаревшая программа также открывает файл в общем режиме (обычно по умолчанию в приложениях Windows); кроме того, если ваше приложение получает блокировку так же, как устаревшее приложение пытается то же самое (состояние гонки), устаревшее приложение не удастся.
      • это чрезвычайно навязчиво и подвержено ошибкам. Если новое приложение и устаревшее приложение не нуждаются в синхронизированном доступе для записи в один и тот же файл, и вы готовы обработать возможность отказа в открытии файла устаревшего приложения, не используйте этот метод.
    • попытка выяснить, какие файлы открыты в наследство применение, используя те же методы, что и ProcessExplorer создан (эквивалент для *Nix-ы lsof)
      • вы еще более уязвимы к условиям гонки, чем независимая от ОС техника
  3. Linux / etc.: кроме того (или вместо) метода, независимого от ОС, вы можете попытаться использовать ту же технику, что и lsof или, в некоторых системах, просто проверьте, какой файл, символическая ссылка /proc/<pid>/fd/<fdes> указывает на
    • вы еще более уязвимы к условиям гонки, чем независимая от ОС техника
    • маловероятно, что устаревшее приложение использует блокировку, но если это так, блокировка не является реальной опцией, если устаревшее приложение не может обрабатывать заблокированный файл изящно (путем блокировки, а не сбоя - и если ваше собственное приложение может гарантировать, что файл не останется заблокированным, блокируя устаревшее приложение для периодов расширения время.)

обновление 2

если предпочтение "проверить, имеет ли устаревшее приложение файл открыт" (интрузивный подход, склонный к условиям гонки), то вы можете решить указанное условие гонки по:

  1. проверка того, открыт ли файл в устаревшем приложении (a la lsof или ProcessExplorer)
  2. приостановка устаревшего процесса подачи заявок
  3. повторение регистрации Шаг 1, чтобы подтвердить, что устаревшее приложение не открывало файл между шагами 1 и 2; задержка и перезапуск на шаге 1, если это так, в противном случае перейдите к шагу 4
  4. doing your business on the file -- в идеале просто переименовать его для последующей независимой обработки, чтобы сохранить устаревшее приложение приостановлено на минимальное количество времени
  5. возобновление процесса устаревших приложений

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


одна вещь, которую я сделал, - это очень временное переименование файла python. Если мы можем переименовать его, то никакой другой процесс не использует его. Я только проверил это на Windows.