在 Python 中等待 Windows 文件 I/O 完成
Posted
技术标签:
【中文标题】在 Python 中等待 Windows 文件 I/O 完成【英文标题】:Wait for Windows file I/O to complete in Python 【发布时间】:2014-03-09 00:05:30 【问题描述】:我有一组系统测试,它们会启动一些进程、创建文件等,然后将它们全部关闭并删除文件。
我在清理时遇到两个间歇性错误:
在由其中一个进程创建的日志文件上:
os.remove(log_path)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process: <path_to_file>
尝试使用shutil.rmtree
删除输出目录时:
File "C:\Python27\lib\shutil.py", line 254, in rmtree
os.rmdir(path)
WindowsError: [Error 145] The directory is not empty: 'C:\\TestTarget\\xxx'
如果我在整理之前插入 2 秒延迟,这两个错误都会消失,所以我认为问题在于 Windows 释放文件所需的时间。显然我想避免延迟测试,有没有办法等到文件系统赶上?
【问题讨论】:
你可以在一个循环中插入一个try
块并循环直到它成功......这行得通吗?
这是一个合理的权宜之计,谢谢。如果有的话,我想要一个更清洁的解决方案。
我认为只要进程在关闭时正确关闭文件,应该可以立即删除。您可能会寻找问题的真正原因。 :-)
我也遇到过类似的问题。我认为这要么是防病毒软件的问题,要么是 NTFS 中的错误。根据我的经验,它通常会很快解决,因此最简单的解决方法是检测故障,短暂延迟(可能 10 毫秒),然后循环重试。
这里有同样的问题。我正在删除一个目录 shutil.rmtree(),然后使用 os.rename() 将另一个目录重命名为相同的目录,并收到错误“当该文件已存在时无法创建文件”。在我看来有点荒谬,我正在尝试使用 python 作为跨平台的 shell/batch 替换,而且我绝对从未在 shell 或批处理脚本中看到过这种类型的问题。
【参考方案1】:
我遇到了类似的问题,我花了几个月的时间寻找合适的解决方案,但一无所获。对我来说,这个问题只发生在使用 python2.7 在 Windows 上运行我的脚本时。在python3上大部分时间都没有问题。在 GNU/Linux 上,我可以在没有这种肮脏解决方案的情况下使用文件操作。
我最终将这个函数用于 Windows 的任何文件操作:try_fail_wait_repeat(见下文),你应该做类似的事情。您也可以将睡眠设置为不同的值。
import sys
import shutil
import time
import os
IS_WINDOWS = (sys.platform == "win32")
if IS_WINDOWS:
maximum_number_of_tries = 40
def move_folder(src, dst):
return try_fail_wait_repeat(maximum_number_of_tries, _move_dir, src, dst)
def read_file(path):
return try_fail_wait_repeat(maximum_number_of_tries, _read_file, path)
else:
def move_folder(src, dst):
return shutil.move(src, dst)
def read_file(path):
return _read_file(path)
def _read_file(file_path):
with open(file_path, "rb") as f_in:
data = f_in.read().decode("ISO-8859-1")
return data
def try_fail_wait_repeat(maximum_number_of_tries, func, *args):
"""A dirty solution for a dirty bug in windows python2"""
i = 0
while True:
try:
res = func(*list(args))
return res
except WindowsError as e:
i += 1
time.sleep(0.5)
if i > maximum_number_of_tries:
print("Too much trying to run ()".format(func, args))
raise e
【讨论】:
【参考方案2】:你使用的函数只删除空目录
尝试:
import shutil
shutil.rmtree('/folder_path')
另外,请尝试在关闭进程之前添加睡眠间隔。
【讨论】:
我发现 rmtree 调用 os.rmdir(path) 并且仍然给出相同的错误。 ```clear_directory 中的 clear_directory() shutil.rmtree(download_dir) 文件“C:\python27_x64\lib\shutil.py”,第 247 行,在 rmtree rmtree(fullname, ignore_errors, onerror) 文件“C:\python27_x64\lib\ shutil.py",第 256 行,在 rmtree onerror(os.rmdir, path, sys.exc_info()) 文件 "C:\python27_x64\lib\shutil.py",第 254 行,在 rmtree os.rmdir(path) WindowsError : [错误 145] 目录不为空: 'D:\\downloads\\test' '''以上是关于在 Python 中等待 Windows 文件 I/O 完成的主要内容,如果未能解决你的问题,请参考以下文章