Python – 如何检查一个文件是否被另一个应用程序使用?

我想打开一个由另一个应用程序定期写入的文件。 这个应用程序不能被修改。 因此,我只想打开文件,当我知道它没有被其他应用程序写入。

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

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

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

我意识到这可能是操作系统的依赖,所以这可能不是真正的python相关现在。

您的Python脚本是否希望打开文件以供书写或阅读? 遗留应用程序是在写入之间打开还是关闭文件,还是保持打开状态?

我们理解遗留应用程序正在做什么以及你的python脚本试图实现什么是非常重要的。

这个功能区域与操作系统高度相关,不能控制遗留应用程序的事实只会让事情变得更加困难。 无论是pythonic还是非pythonic的做法可能是你最担心的问题 – 难的问题是,你是否试图实现将是可能的。


UPDATE

好的,从你的评论中知道:

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

那么问题的参数就会改变。 实际上,在一些假设条件下,可以独立于操作系统的方式来完成,或者作为操作系统依赖和操作系统无关的技术的组合。 🙂

  1. 与操作系统无关的方式 :如果假定遗留应用程序保持打开最多一些已知时间(例如打开文件,执行一次写入,然后关闭文件)的时间(例如T秒)是安全的,大约每X秒打开一次,其中X大于2 * T
    • stat文件
    • now()减去文件的修改时间now() ,产生D
    • 如果T <= D < X那么打开文件,并做它你需要的
    • 这对您的应用程序来说可能足够安全 T / X下降,安全性增加 在* nix上,您可能需要仔细检查/etc/ntpd.conf以确定正确的时间步长和摆动配置(请参阅修补程序)。 对于Windows请参阅MSDN
  2. Windows :除上述独立于操作系统的方法之外(或代替),您可以尝试使用以下任一方法:
    • 共享(锁定):这假定传统程序也以共享模式打开文件(通常是Windows应用程序中的默认文件)。 此外,如果您的应用程序像传统应用程序尝试相同(争用条件)一样获取锁定,则传统应用程序将失败。
      • 这是非常干扰和容易出错的。 除非新应用程序和传统应用程序都需要同步访问才能写入同一个文件,并且您愿意处理传统应用程序被拒绝打开文件的可能性,否则请勿使用此方法。
    • 试图找出遗留应用程序中打开的文件,使用与ProcessExplorer相同的技术(相当于* nix的lsof
      • 与独立于操作系统的技术相比,您更容易受到竞争的影响
  3. Linux的/等。 :除了上面独立于操作系统的方法之外(或者代替),您可能会试图使用与lsof相同的技术,或者在某些系统上只检查哪个文件符号链接/proc/<pid>/fd/<fdes>指向
    • 与独立于操作系统的技术相比,您更容易受到竞争的影响
    • 遗留应用程序使用锁定的可能性很小,但如果是这样的话,锁定不是一个真正的选择,除非传统应用程序可以正常处理锁定的文件(通过阻塞而不是失败 – 并且如果您自己的应用程序可以保证文件将不会保持锁定状态,从而阻止传统应用程序延长一段时间。)

更新2

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

  1. 检查遗留应用程序是否打开文件(一个或者多个ProcessExplorer
  2. 暂停传统的应用程序进程
  3. 重复步骤1中的检查以确认传统应用程序在步骤1和步骤2之间没有打开文件; 如果是,则在步骤1延迟并重新启动,否则继续执行步骤4
  4. 在文件上进行业务 – 理想情况下只需将其重命名为随后的独立处理,以便将遗留应用程序暂停最少的时间
  5. 恢复传统的应用程序进程

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

有一件事我已经做了python非常暂时重命名文件。 如果我们能够重命名它,那么没有其他进程正在使用它。 我只在Windows上测试过。