有人可以向我解释为什么shutil.rmtree会抛出错误,说目录不是空的吗?
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 810, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "W:\__init__.py", line 90, in makePatch
myprog.copy_data()
File "W:\myprog.py", line 143, in copy_data
self.cleanupTempDir()
File "W:\myprog.py", line 138, in cleanupTempDir
shutil.rmtree(self.TEMP_DIR)
File "C:\Python27\lib\shutil.py", line 247, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 256, in rmtree
onerror(os.rmdir, path, sys.exc_info())
File "C:\Python27\lib\shutil.py", line 254, in rmtree
os.rmdir(path)
WindowsError: [Error 145] The directory is not empty: u'e:\\PatchData\\Data'
答案 0 :(得分:1)
看起来这些文件被标记为只读。在复制文件后添加一行以删除只读标志后,我不再收到此错误。奇怪的是,它甚至不会尝试删除文件,或者至少不会在文件上引发任何例外目录。
答案 1 :(得分:0)
Linux:我在处理临时文件夹时也遇到了这个错误:我在 os.makedirs
构造函数中有一个 __init__
调用和一个 shutil.rmtree
调用在 __del__
解构器中,代码使用了 multiprocessing
库;该文件夹是按顺序构造的,但每当进程终止时就会被销毁。因此,错误并不总是可重现,但据说只有当两个进程试图同时销毁文件夹时才会发生,并且没有适当的锁定机制,才会抛出这些错误。之所以发生这种情况,是因为出于某种未知原因,__del__
析构函数被调用了不止一次。
错误如下:
Exception ignored in: <function VideoMaker.__del__ at 0x7f6066a888b0>
Traceback (most recent call last):
File "VideoMaker.py", line 49, in __del__
onerror(os.unlink, fullname, sys.exc_info())
File "/home/Marco/miniconda3/lib/python3.8/shutil.py", line 670, in _rmtree_safe_fd
onerror(os.rmdir, path, sys.exc_info())
File "/home/Marco/miniconda3/lib/python3.8/shutil.py", line 717, in rmtree
_rmtree_safe_fd(fd, path, onerror)
shutil.rmtree(self.temp_videoclip_dir)
File "/home/Marco/miniconda3/lib/python3.8/shutil.py", line 672, in _rmtree_safe_fd
File "/home/Marco/miniconda3/lib/python3.8/shutil.py", line 715, in rmtree
onerror(os.unlink, fullname, sys.exc_info())
File "/home/Marco/miniconda3/lib/python3.8/shutil.py", line 670, in _rmtree_safe_fd
os.unlink(entry.name, dir_fd=topfd)
FileNotFoundError: [Errno 2] No such file or directory: '12.mp4'
或
OSError: [Errno 39] Directory not empty: 'tmp/tmp.videoclips/'
rmtree
析构函数中使用 __del__
:对象解构器可能并不总是具有可预测的行为,因此避免在内部使用操作系统的 IO 操作。而是创建一个单独的函数并在对象范围的末尾调用它。
LOCK
文档:
文档示例:Synchronization between processes
l.acquire()
try:
if os.path.isdir(path_to_delete):
shutil.rmtree(path_to_delete)
finally:
l.release()
def try_to_rmtree(can_still_retry):
if can_still_retry:
try:
if os.path.isdir(path_to_delete):
shutil.rmtree(path_to_delete)
except:
try_to_rmtree(can_still_retry -1)
can_still_retry = 5
try_to_rmtree(can_still_retry)