Python-как проверить, используется ли файл другим приложением?
Я хочу открыть файл, который периодически записываются в другое приложение. Это приложение не может быть изменено. Поэтому я хотел бы открыть файл только тогда, когда я знаю, что он не был написан другим приложением.
есть ли подходящие для Python способ сделать это? В противном случае, как я могу достичь этого в Unix и Windows?
редактировать: я постараюсь уточнить. есть ли способ проверить, был ли текущий файл открыт другим заявление?
Я хотел бы начать с этого вопроса. Является ли это другое приложение чтение/запись не имеет значения на данный момент.
Я понимаю, что это, вероятно, зависит от ОС, поэтому сейчас это может быть не связано с python.
3 ответов
будет ли ваш скрипт python желать открыть файл для записи или для чтения? Является ли устаревшее приложение открытием и закрытием файла между записями или сохраняет его открытым?
чрезвычайно важно, чтобы мы понимали, что делает устаревшее приложение и чего пытается достичь ваш скрипт python.
эта область функциональности сильно зависит от ОС, и тот факт, что у вас нет контроля над устаревшим приложением, только делает вещи к сожалению, сложнее. Есть ли данные или не подходящие для Python способ сделать это, вероятно, наименьшая из ваших проблем - трудный вопрос, будет ли то, что вы пытаетесь достичь будет невозможно.
обновление
Итак, зная (из вашего комментария), что:
устаревшие приложения и закрытие файла каждые X минут, но Я не хочу предполагать, что при t = t_0 + n*X + eps он уже закрыт папка.
параметры задачи изменяются. На самом деле это может быть сделано независимым от ОС способом с учетом нескольких предположений или как комбинация зависимых от ОС и независимых от ОС методов. :)
-
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
-
-
окна: кроме того (или вместо) метода, независимого от ОС, вы можете попытаться использовать либо:
- общий доступ (блокировка): это предполагает, что устаревшая программа также открывает файл в общем режиме (обычно по умолчанию в приложениях Windows); кроме того, если ваше приложение получает блокировку так же, как устаревшее приложение пытается то же самое (состояние гонки), устаревшее приложение не удастся.
- это чрезвычайно навязчиво и подвержено ошибкам. Если новое приложение и устаревшее приложение не нуждаются в синхронизированном доступе для записи в один и тот же файл, и вы готовы обработать возможность отказа в открытии файла устаревшего приложения, не используйте этот метод.
- попытка выяснить, какие файлы открыты в наследство применение, используя те же методы, что и ProcessExplorer создан (эквивалент для *Nix-ы
lsof
)- вы еще более уязвимы к условиям гонки, чем независимая от ОС техника
- общий доступ (блокировка): это предполагает, что устаревшая программа также открывает файл в общем режиме (обычно по умолчанию в приложениях Windows); кроме того, если ваше приложение получает блокировку так же, как устаревшее приложение пытается то же самое (состояние гонки), устаревшее приложение не удастся.
-
Linux / etc.: кроме того (или вместо) метода, независимого от ОС, вы можете попытаться использовать ту же технику, что и
lsof
или, в некоторых системах, просто проверьте, какой файл, символическая ссылка/proc/<pid>/fd/<fdes>
указывает на- вы еще более уязвимы к условиям гонки, чем независимая от ОС техника
- маловероятно, что устаревшее приложение использует блокировку, но если это так, блокировка не является реальной опцией, если устаревшее приложение не может обрабатывать заблокированный файл изящно (путем блокировки, а не сбоя - и если ваше собственное приложение может гарантировать, что файл не останется заблокированным, блокируя устаревшее приложение для периодов расширения время.)
обновление 2
если предпочтение "проверить, имеет ли устаревшее приложение файл открыт" (интрузивный подход, склонный к условиям гонки), то вы можете решить указанное условие гонки по:
- проверка того, открыт ли файл в устаревшем приложении (a la
lsof
илиProcessExplorer
) - приостановка устаревшего процесса подачи заявок
- повторение регистрации Шаг 1, чтобы подтвердить, что устаревшее приложение не открывало файл между шагами 1 и 2; задержка и перезапуск на шаге 1, если это так, в противном случае перейдите к шагу 4
- doing your business on the file -- в идеале просто переименовать его для последующей независимой обработки, чтобы сохранить устаревшее приложение приостановлено на минимальное количество времени
- возобновление процесса устаревших приложений
Unix не имеет блокировки файлов по умолчанию. Лучшим предложением для среды Unix было бы посмотреть на источники для команды lsof. Он имеет глубокие знания о том, какой процесс какие файлы открывать. Вы можете использовать это как основу вашего решения. Вот источники Ubuntu для lsof.
одна вещь, которую я сделал, - это очень временное переименование файла python. Если мы можем переименовать его, то никакой другой процесс не использует его. Я только проверил это на Windows.