Python - 如何检查另一个应用程序是否使用了某个文件?

时间:2009-02-26 06:44:48

标签: python windows unix logging file-io

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

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

编辑:我会尽力澄清。 有没有办法检查当前文件是否已被其他应用程序打开?

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

我意识到它可能依赖于操作系统,所以现在可能并不真正与python相关。

3 个答案:

答案 0 :(得分:7)

你的python脚本是否希望打开文件进行书写或阅读?遗留应用程序是在写入之间打开和关闭文件,还是将其保持打开状态?

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

这个功能区域高度依赖于操作系统,而且您无法控制遗留应用程序这一事实使得事情变得更加困难。无论是采用pythonic还是非pythonic方式,这可能是您最不关心的问题 - 难以理解的问题将是您想要实现的目标是否可行。


<强>更新

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

  

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

然后问题的参数发生了变化。实际上,它可以在一些独立于OS的方式中完成,只需要一些假设,或者作为OS依赖和OS独立技术的组合。 :)

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

  4. 更新2

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

    1. 检查旧版应用程序是否打开了文件(la /proc/<pid>/fd/<fdes>lsof
    2. 暂停旧版申请流程
    3. 重复步骤1中的检查以确认遗留应用程序未在步骤1和2之间打开文件;如果是,则在步骤1延迟并重新启动,否则继续执行步骤4
    4. 在文件上开展业务 - 理想情况下,只需将其重命名为后续独立处理,以便将遗留应用程序暂停一段时间
    5. 恢复遗留申请流程

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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