Windows/Python 检查文件是否打开或正在使用

我正在使用 python 来监视文件夹并检查文件是否正在被复制,如果是,则将它们复制到新位置。 我正在使用以下内容来监视文件夹: fsmonitor 我面临的问题是我无法辨别该文件是否正在使用中以及当前是否正在将内容写入磁盘。如果是这样,我想等到复制完成,然后开始将其复制到我的新位置。

那么如何确定文件是否正在使用/打开? 我在这里看到了一些建议,我尝试写入文件问题,如果失败,则表明该文件正在使用中: example answer (I've seen similar in python) 但是我不愿意使用这种方法,因为担心它可能会导致腐败等问题。 有没有替代/更安全的方法来做到这一点?或者测试写权限安全吗? 有人熟悉pywin32吗?它提供这样的工具吗?该网站看起来很神秘,所以想知道它是否有 windows 提供的最新 API,即使上面提到的 fsmointor 也使用相同的库,我想知道是否有更新/更有效的方法来做到这一点。

目前,我正在使用 psutil、proc.open_files() 循环遍历所有进程和所有文件以列出打开的文件。如果我担心的文件出现在此列表中,我会等待并重试。然而,这个过程创建了一个庞大的文件列表,并使用了我 12% 的 CPU 来创建它,所以我迫切需要一个替代方案。

回应阿德里安·麦卡锡 我一开始假设 fsmonitor 输出的任何内容都是安全的,但是如果您看到以下输出 which si 是单个文件副本:

0 86 0 创建 C:\Users\ScanUser\Pictures\syncTest dotnet-sdk-5.0.203-win-x64 - Copy.exe 3684bf38 创建 C:\Users\ScanUser\Pictures\syncTest dotnet-sdk-5.0.203-win-x64 - Copy.exe 3684bf38 0 86 0 修改 C:\Users\ScanUser\Pictures\syncTest dotnet-sdk-5.0.203-win-x64 - Copy.exe a8cf3250 修改 C:\Users\ScanUser\Pictures\syncTest dotnet-sdk-5.0.203-win-x64 - Copy.exe a8cf3250 0 160 0 修改 C:\Users\ScanUser\Pictures\syncTest dotnet-sdk-5.0.203-win-x64 - Copy.exe caef5c64 修改 C:\Users\ScanUser\Pictures\syncTest dotnet-sdk-5.0.203-win-x64.exe caef5c64 修改 C:\Users\ScanUser\Pictures\syncTest dotnet-sdk-5.0.203-win-x64 - Copy.exe caef5c64 修改 C:\Users\ScanUser\Pictures\syncTest dotnet-sdk-5.0.203-win-x64.exe caef5c64

所以难题是我应该从哪个“修改”开始复制文件?我可以等待几分钟/几秒钟,看看该文件是否出现了另一个“修改”,但是我如何决定通过 SFTP 等待大文件的时间可能需要 30 分钟,所以我需要一些可扩展的东西。 另外,我不希望对文件执行多次复制操作,因为这会使脚本效率低下。

zhangjuntu 回答:Windows/Python 检查文件是否打开或正在使用

这可以帮助你 check if a file is open in Python 这是一个代码:

try: # try to open the file
   with open("file","r") as file: 
       # some code here
except IOError:
   # if it throws an error that means it is in use
,

我认为您不必要地担心在另一个进程仍然打开文件时处理该文件。

在 Windows 上。 fsmonitor 使用 ReadDirectoryChangesW 机制。这意味着您将在之后收到有关更改的通知。因此,如果进程写入 foo.log,您将在写入操作完成后收到通知。 (其实我觉得是在目录元数据更新之后。)

要复制文件,您需要读取权限。所以请继续打开它进行阅读。

如果它打开,那么即使另一个进程打开它,也可以安全阅读。即使另一个进程正在写入文件,您也无法通过读取文件来破坏它。

如果它无法打开,则另一个进程将其打开并故意阻止其他进程读取它(可能是因为他们知道他们会主动更新它)。在这种情况下,您可以稍后再试。

尝试首先检查另一个进程是否正在使用该文件实际上并没有帮助,因为在您检查和尝试对该信息采取行动的那一刻之间,答案可能会发生变化。 当您打开文件时,系统会在互斥锁* 下进行权限检查和打开,因此答案不能在两者之间更改。您无法从用户模式代码中自行模拟。打开文件后,您就可以安全地使用它了。

如果您在另一个进程尝试写入文件的同时尝试读取文件,系统将确保读取将获得写入前或写入后的数据。它不会得到新旧混合的结果。

也就是说,如果您正在通过一系列小型读取操作读取文件,而另一个进程正在使用一系列小型写入操作写入文件,则您可能会捕获文件的某些中间状态。不过没关系。原始文件没有受到损害,这些写入将触发另一个 fsmonitor 通知,因此您的代码将重新开始并尝试制作该文件的另一个副本。


* 我在一般意义上使用“互斥锁”:它使用某种同步机制,但不一定是 Windows 互斥锁对象。

本文链接:https://www.f2er.com/2260.html

大家都在问