有没有一种方法可以等待os.remove()完成?

3

有没有一种方法可以等待os.remove()完成?我有一个脚本,每天制作一些png图片,并首先删除旧的,以便从旧的更新的是真正被制作的图片。

问题是-我猜-os.remove()没有足够的时间来完成,因为正在制作的文件与正在删除的文件是完全相同的。但是,如果我在os.remove()之后放置一个time.sleep(5),它会起作用。

代码类似于以下内容:

...some imports

for root, dirs, files in os.walk(trgt_folder):
    [os.remove(os.path.join(root, file)) for file in files if 'png' in file]
make_and_save_newpics(trgt_folder)

如果你不是在构建一个列表,就不要使用列表推导式。这会使你的代码变得不清晰。 - khelwood
循环检查os.listdir(trgt_folder),直到找不到PNG文件。不幸的是,您不能使用os.path.isfileos.path.exists,因为它们调用stat,即使文件仍然存在但已被“删除”(但尚未取消链接)的文件也会失败,因为这些文件处于一种状态,防止对它们进行任何访问。在Windows中更好的检查方式是通过模式“*.png”的FindFirstFile。然而,Python标准库不直接支持此功能。它只有listdir,如果目录中有数千个文件,则相对昂贵。 - Eryk Sun
通常这不是问题。remove 调用 WinAPI 的 DeleteFile,该函数调用 NtOpenFile 获取句柄,调用 NtSetInformationFile 设置其删除状态,并调用 NtClose 关闭句柄,如果没有其他文件引用,则应立即在文件系统的 IRP_MJ_CLEANUP 例程中取消链接并删除文件。潜在的问题是反恶意软件程序打开了第二个引用以扫描文件,这会使文件短暂处于僵尸状态(已删除但未取消链接),直到关闭第二个引用。 - Eryk Sun
2个回答

0

如果您想等待os.remove()完成,我建议您使用线程。在一个线程中调用os.remove()并等待其完成。


0

如果你要覆盖同一个文件,我建议使用更好的解决方案。不要使用 time.sleep(5),而是检查文件是否存在,如果存在则删除该文件并重新保存:

import os
# put this check before file save operation
if os.path.isfile(filepath):
    os.remove(os.path.join(root, file))
    # save new pic after this 
    make_and_save_newpics(trgt_folder)

如果时间是一个限制因素,那么有更好的方法来解决问题,time.sleep(5) 不是一个好的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接