问题描述
我想打开一个由另一个应用程序定期写入的文件。这个应用程序不能被修改。因此,我只想打开文件,当我知道它不是由其他应用程序写入。
有没有pythonic的方式来做到这一点?否则,我如何在Unix和Windows中实现这一点?
编辑:我会尽力澄清。有没有办法检查当前文件是否被另一个应用程序打开?
我想从这个问题开始。是否现在这些其他应用程序读/写是不相关的。
我意识到这可能是操作系统依赖,所以这可能不是真正的python相关。
您的python脚本是否希望打开文件进行写入或读取?遗留应用程序在写入之间打开和关闭文件,还是保持打开状态?
我们理解传统应用程序在做什么以及什么是非常重要的你的python脚本正试图实现。
这个功能的区域依赖于操作系统,而且你不能控制遗留应用程序,这只会让事情变得更加困难。是否有pythonic或非pythonic这样做这样做可能是你最担心的问题 - 难的问题是,你是否有可能尝试实现。
$ b好的,所以从你的评论中知道:(b)你的评论是正确的,
$ b
问题的参数被改变。实际上,在一些假设条件下,可以独立于操作系统的方式来完成,或者作为操作系统依赖和操作系统无关的技术的组合。 :)
$ b
- 与操作系统无关的方式:如果可以安全地假定遗留应用程序保持打开文件(例如,打开文件,执行一次写入,然后关闭文件),并且每次或多或少地重新打开它(例如,至少一些已知的时间,例如
T
其中X
>秒, 。
-
stat
文件
- 从文件的修改时间减去
now()
,产生D
- if
T
< =D
<X
然后打开文件并执行所需的操作
- 这对于您的应用程序来说可能足够安全。随着
T
/X
减少,安全性增加。在* nix上,您可能需要仔细检查/etc/ntpd.conf
,以获得适当的时间步长和摆动配置(请参见修补程序)。有关Windows的信息,请参阅
- 从文件的修改时间减去
- Windows :除上述独立于操作系统的方法之外(或代替),您可以尝试使用:
- 共享(锁定):假定传统程序也以共享模式打开文件(通常是Windows应用程序中的默认文件)。此外,如果您的应用程序像传统应用程序尝试相同(争用条件)一样获取锁定,则传统应用程序将失败。
- 这是非常干扰和容易出错的。除非新应用程序和遗留应用程序需要同步访问才能写入同一文件,并且您愿意处理遗留应用程序被拒绝打开文件的可能性,否则请勿使用此方法。
- 这是非常干扰和容易出错的。除非新应用程序和遗留应用程序需要同步访问才能写入同一文件,并且您愿意处理遗留应用程序被拒绝打开文件的可能性,否则请勿使用此方法。
- 尝试使用与(相当于* nix的
lsof
)
- 与独立于操作系统的技术相比,您甚至更容易受到竞争条件的限制。 除了上述独立于操作系统的方法之外(或代替),您可以尝试使用与<$ c $相同的技术在某些系统上,只要检查哪个文件符号链接
- 你是偶数与独立于操作系统的技术相比,更容易受到竞争情况的影响。传统应用程序使用锁定的可能性非常小,但如果是这样,锁定不是真正的选择,除非传统应用程序可以处理一个被锁定的文件(通过阻塞,而不是失败),并且如果你自己的应用程序可以保证文件不会被锁住,那么阻塞传统的应用程序以延长一段时间。
/ proc /< pid> / fd /< fdes>
指向
- 共享(锁定):假定传统程序也以共享模式打开文件(通常是Windows应用程序中的默认文件)。此外,如果您的应用程序像传统应用程序尝试相同(争用条件)一样获取锁定,则传统应用程序将失败。
更新2 b
如果您偏爱检查遗留应用程序是否打开文件(侵入式方法倾向于竞争条件),那么您可以通过以下方式解决上述竞争条件:
- 检查遗留应用程序是否打开文件(a
lsof
或ProcessExplorer $ c
- 暂停旧应用程序进程
- 重复步骤1中的检查以确认遗留应用程序未打开步骤1和步骤2之间的文件;如果是这样,请延迟并重新启动,否则请继续执行步骤4
- 在文件上进行业务处理 - 理想情况下只需对其进行重命名,以便进行后续独立处理,以便保持遗留应用程序只需要很少的时间
- 恢复传统应用程序进程
- 暂停旧应用程序进程
I want to open a file which is periodically written to by another application. This application cannot be modified. I'd therefore like to only open the file when I know it is not been written to by an other application.
Is there a pythonic way to do this? Otherwise, how do I achieve this in Unix and Windows?
edit: I'll try and clarify. Is there a way to check if the current file has been opened by another application?
I'd like to start with this question. Whether those other application read/write is irrelevant for now.
I realize it is probably OS dependent, so this may not really be python related right now.
Will your python script desire to open the file for writing or for reading? Is the legacy application opening and closing the file between writes, or does it keep it open?
It is extremely important that we understand what the legacy application is doing, and what your python script is attempting to achieve.
This area of functionality is highly OS-dependent, and the fact that you have no control over the legacy application only makes things harder unfortunately. Whether there is a pythonic or non-pythonic way of doing this will probably be the least of your concerns - the hard question will be whether what you are trying to achieve will be possible at all.
UPDATE
OK, so knowing (from your comment) that:
then the problem's parameters are changed. It can actually be done in an OS-independent way given a few assumptions, or as a combination of OS-dependent and OS-independent techniques. :)
- OS-independent way: if it is safe to assume that the legacy application keeps the file open for at most some known quantity of time, say
T
seconds (e.g. opens the file, performs one write, then closes the file), and re-opens it more or less everyX
seconds, whereX
is larger than 2*T
.stat
the file- subtract file's modification time from
now()
, yieldingD
- if
T
<=D
<X
then open the file and do what you need with it - This may be safe enough for your application. Safety increases as
T
/X
decreases. On *nix you may have to double check/etc/ntpd.conf
for proper time-stepping vs. slew configuration (see tinker). For Windows see MSDN
- Windows: in addition (or in-lieu) of the OS-independent method above, you may attempt to use either:
- sharing (locking): this assumes that the legacy program also opens the file in shared mode (usually the default in Windows apps); moreover, if your application acquires the lock just as the legacy application is attempting the same (race condition), the legacy application will fail.
- this is extremely intrusive and error prone. Unless both the new application and the legacy application need synchronized access for writing to the same file and you are willing to handle the possibility of the legacy application being denied opening of the file, do not use this method.
- attempting to find out what files are open in the legacy application, using the same techniques as ProcessExplorer (the equivalent of *nix's
lsof
)- you are even more vulnerable to race conditions than the OS-independent technique
- sharing (locking): this assumes that the legacy program also opens the file in shared mode (usually the default in Windows apps); moreover, if your application acquires the lock just as the legacy application is attempting the same (race condition), the legacy application will fail.
- Linux/etc.: in addition (or in-lieu) of the OS-independent method above, you may attempt to use the same technique as
lsof
or, on some systems, simply check which file the symbolic link/proc/<pid>/fd/<fdes>
points to- you are even more vulnerable to race conditions than the OS-independent technique
- it is highly unlikely that the legacy application uses locking, but if it is, locking is not a real option unless the legacy application can handle a locked file gracefully (by blocking, not by failing - and if your own application can guarantee that the file will not remain locked, blocking the legacy application for extender periods of time.)
UPDATE 2
If favouring the "check whether the legacy application has the file open" (intrusive approach prone to race conditions) then you can solve the said race condition by:
- checking whether the legacy application has the file open (a la
lsof
orProcessExplorer
) - suspending the legacy application process
- repeating the check in step 1 to confirm that the legacy application did not open the file between steps 1 and 2; delay and restart at step 1 if so, otherwise proceed to step 4
- doing your business on the file -- ideally simply renaming it for subsequent, independent processing in order to keep the legacy application suspended for a minimal amount of time
- resuming the legacy application process
这篇关于Python - 如何检查一个文件是否被另一个应用程序使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!