我正在构建一个相对简单的应用程序,该应用程序询问目录,检查目录是否正确,然后删除其中一个目录,并使用另一个目录的内容重新创建它。我遇到这种奇怪的行为,我将尝试解释:
当我打开目标文件夹窗口,并且它是空的时,有一个拒绝访问的异常,然后我被踢出该文件夹并将其删除。但是,如果它不为空,则可以正常工作,没有异常,目标目录(从表面看来)将被清空,然后填充源目录中的文件。这很奇怪,因为无论如何它都应该直接删除目标文件夹,然后使用与源目标相同的名称和内容重新创建它。
这对我来说没有意义,当我浏览目录时,如果目录不为空,则目录是否为空,是否应该存在完全相同的例外?有什么区别,仍然应该删除文件夹。有什么合乎逻辑的解释吗?另外,如果有例外,为什么仍然要删除目录?
此特定部分的代码非常简单(请记住,我是一个初学者:))
def Delete(self, dest):
try:
shutil.rmtree(dest)
self.Paste(self.src, dest)
except (IOError, os.error) as e:
print e
def Paste(self, src, dest):
try:
shutil.copytree(src, dest)
except (IOError, os.error) as e:
print e
这是Windows上的预期行为。
内部shutil.rmtree
调用MSDN(DeleteFile
)上记录的Windows API函数http://msdn.microsoft.com/en-us/library/windows/desktop/aa363915%28v=vs.85%29.aspx。
此功能具有以下属性(我高亮):
DeleteFile函数将文件标记为在关闭时要删除。 因此,在关闭文件的最后一个句柄之前,不会删除文件。随后对CreateFile的调用以打开文件失败,并显示ERROR_ACCESS_DENIED。
如果其他任何进程仍然打开了句柄(例如,病毒扫描程序,Windows资源管理器,因为您正在观看目录或该目录可能仍具有句柄的其他任何东西,则它将不会消失。
通常,您只需在粘贴操作中捕获该异常,然后重试几次/几十毫秒,以处理所有这些奇怪的病毒扫描程序异常。
小额奖励:您可以使用windbg或ProcessExplorer来找出谁仍对文件保持打开句柄(只需使用Process Explorer中的Find Handle并搜索文件名)。