【问题标题】:Python - How to check if a file is used by another application?Python - 如何检查文件是否被另一个应用程序使用?
【发布时间】:2009-02-26 06:44:48
【问题描述】:

我想打开一个由另一个应用程序定期写入的文件。此应用程序无法修改。因此,我只想在知道该文件未被其他应用程序写入时才打开该文件。

有没有pythonic的方法来做到这一点?否则,我如何在 Unix 和 Windows 中实现这一点?

编辑:我会试着澄清一下。 有没有办法检查当前文件是否已被另一个应用程序打开?

我想从这个问题开始。那些其他应用程序读/写现在是否无关紧要。

我意识到它可能依赖于操作系统,所以现在这可能与 python 无关。

【问题讨论】:

  • 你想实现日志轮换吗??
  • 不完全是,但也不算太远。我想在现有应用程序的基础上构建一个应用程序。

标签: python windows unix logging file-io


【解决方案1】:

您的 python 脚本是否希望打开文件进行写入或读取?旧版应用程序是在写入之间打开和关闭文件,还是保持打开状态?

了解遗留应用程序在做什么以及您的 python 脚本试图实现什么是非常重要的。

这方面的功能高度依赖于操作系统,不幸的是,您无法控制遗留应用程序这一事实只会让事情变得更加困难。是否有 python 或非 python 的方式来做到这一点可能是你最不关心的问题 - 难题将是你想要实现的目标是否可能。


更新

好的,所以(从您的评论中)知道:

旧版应用程序正在打开并且 每 X 分钟关闭一次文件,但是 我不想假设在 t = t_0 + n*X + eps 它已经关闭 文件。

然后更改问题的参数。它实际上可以在给定一些假设的情况下以独立于操作系统的方式完成,或者作为独立于操作系统的技术和独立于操作系统的技术的组合来完成。 :)

  1. 独立于操作系统的方式:如果可以安全地假设遗留应用程序最多保持文件打开某个已知时间量,例如T 秒(例如打开文件,执行一次写入,然后关闭文件),然后或多或少地每隔X 秒重新打开一次,其中X 大于2*T
    • stat文件
    • now() 中减去文件的修改时间,得到D
    • 如果 T D X 然后打开文件并用它做你需要的事情
    • 这对您的应用程序来说可能足够安全。随着T/X 的降低,安全性提高。在 *nix 上,您可能必须仔细检查 /etc/ntpd.conf 以了解正确的时间步长与转换配置(请参阅修补程序)。对于 Windows,请参阅 MSDN
  2. Windows:除了(或替代)上述独立于操作系统的方法之外,您还可以尝试使用以下任一方法:
    • 共享(锁定):这假定遗留程序也以共享模式打开文件(通常是 Windows 应用程序中的默认设置);此外,如果您的应用程序在旧应用程序尝试相同(竞争条件)时获取锁,则旧应用程序将失败。
      • 这非常具有侵入性并且容易出错。除非新应用程序和旧应用程序都需要同步访问以写入同一文件,并且您愿意处理旧应用程序被拒绝打开文件的可能性,否则不要使用此方法。
    • 使用与ProcessExplorer 相同的技术(相当于*nix 的lsof)尝试找出遗留应用程序中打开的文件
      • 与独立于操作系统的技术相比,您更容易受到竞争条件的影响
  3. Linux/etc.:除了(或替代)上述独立于操作系统的方法之外,您可以尝试使用与lsof 相同的技术,或者在某些系统上,只需检查哪个文件符号链接/proc/<pid>/fd/<fdes> 指向
    • 与独立于操作系统的技术相比,您更容易受到竞争条件的影响
    • 遗留应用程序使用锁定的可能性很小,但如果是,锁定不是一个真正的选择,除非遗留应用程序可以优雅地处理锁定文件(通过阻塞,而不是通过失败 - 并且如果您自己的应用程序可以保证文件将不会保持锁定状态,从而在较长时间内阻止旧版应用程序。)

更新 2

如果支持“检查遗留应用程序是否打开文件”(容易出现竞争条件的侵入性方法),那么您可以通过以下方式解决所述竞争条件:

  1. 检查旧版应用程序是否打开了文件(例如lsofProcessExplorer
  2. 暂停旧版申请流程
  3. 重复步骤 1 中的检查以确认遗留应用程序在步骤 1 和 2 之间没有打开文件;如果是,则延迟并在第 1 步重新开始,否则继续第 4 步
  4. 在文件上开展业务 - 理想情况下,只需将其重命名以进行后续独立处理,以使旧版应用程序暂停的时间最短
  5. 恢复旧版申请流程

【讨论】:

  • 旧版应用程序每隔 X 分钟打开和关闭文件,但我不想假设在 t = t_0 + n*X + eps 它已经关闭了文件。
【解决方案2】:

Unix 默认没有文件锁定。我对 Unix 环境的最佳建议是查看 lsof 命令的源代码。它对哪个进程打开了哪些文件有深入的了解。您可以将其用作解决方案的基础。这里是Ubuntu sources for lsof.

【讨论】:

  • 这看起来可能是 Unix 上的一个很好的解决方案。我可以在访问之前解析 lsof 的输出以获得我需要的文件。没有锁不是完全安全的,但我只能在 99.99% 的情况下处理正确性。我只需要一个适用于 Windows 的解决方案。
【解决方案3】:

我做过的一件事是让 python 临时重命名文件。如果我们能够重命名它,那么没有其他进程正在使用它。我只在 Windows 上测试过。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 2010-11-06
    • 2014-07-12
    • 1970-01-01
    • 2014-03-26
    • 2013-01-09
    相关资源
    最近更新 更多