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

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

Есть ли питонский способ сделать это? Иначе как мне добиться этого в Unix и Windows?

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

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

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

Ответы [ 3 ]

7 голосов
/ 26 февраля 2009

Желает ли ваш скрипт на python открыть файл для записи или для чтения? Устаревшее приложение открывает и закрывает файл между операциями записи или оно остается открытым?

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

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


UPDATE

ОК, поэтому, зная (из вашего комментария), что:

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

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

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

ОБНОВЛЕНИЕ 2

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

  1. проверка, открыт ли файл у устаревшего приложения (а-ля lsof или ProcessExplorer)
  2. приостановка устаревшего процесса подачи заявки
  3. повторение проверки на шаге 1, чтобы подтвердить, что устаревшее приложение не открывало файл между шагами 1 и 2; задержите и перезапустите на шаге 1, если это так, в противном случае перейдите к шагу 4
  4. ведение бизнеса с файлом - в идеале просто переименуйте его для последующей независимой обработки, чтобы устаревшее приложение было приостановлено на минимальное время
  5. возобновление устаревшего процесса подачи заявки
0 голосов
/ 26 февраля 2009

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

0 голосов
/ 26 февраля 2009

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

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