Python 删除文件时出现 WindowsError 5,即使我拥有完全权限

Python getting WindowsError 5 when deleting a file even though I have full permissions

关于 Python 关于 windows 的快速问题。 我有一个编译程序的脚本(使用安装规则),然后通过网络将构建产品移动到远程目标。

但是,我一直收到 WindowsError 5 Access Denied。 所有文件都是从脚本上下文创建的,我拥有所有这些文件的所有权和完全控制权。复制到远程目标成功,但失败是在删除过程中。 如果我尝试在 windows 内手动删除或重命名文件,我不会收到任何错误。只是 shutil.move 失败了。

我在想,也许 API 正在尝试在网络操作尚未完成时删除文件?

非常感谢任何意见。

try:
    shutil.move(directory, destination)
except OSError:
    print "Failed to move %s to %s." %(directory, destination)
    raise

...

Traceback (most recent call last):
  File "C:\WIP\BuildMachine\build_machine.py", line 176, in <module>
    main()
  File "C:\WIP\BuildMachine.hg\BuilderInstance.py", line 496, in deployVersion
    shutil.move(directory, destination)
  File "C:\Python27\lib\shutil.py", line 300, in move
    rmtree(src)
  File "C:\Python27\lib\shutil.py", line 252, in rmtree
    onerror(os.remove, fullname, sys.exc_info())
  File "C:\Python27\lib\shutil.py", line 250, in rmtree
    os.remove(fullname)
WindowsError: [Error 5] Access is denied: '3_54_7__B_1\Application_Release_Note.doc'

windows 上 shutil.move 的问题在于它无法处理以下情况:

  • 源和目标不在同一驱动器上并且
  • 源目录中的一些文件被写保护。

如果两个条件都满足,shutil.move不能执行os.rename,它必须:

  • 复制文件(这不是问题)
  • 删除源文件(由于shutil的限制,一个问题)

为了解决这个问题,我为自己制作了一个 shutil 模块的副本(使用不同的名称)并添加了该行(对于您来说它就在第 250 行之前):

   os.chmod(fullname,0o777)  # <-- add that line
   os.remove(fullname)  # some versions have "unlink" instead

rmtree 函数在 Windows 上有同样的问题。

在 Linux 上不会发生这种情况,因为文件删除权限不是在文件级别而是在目录级别处理的。在 windows 上,它不是那样工作的。添加 os.chmod 就可以了(即使它是 hack),并且 os.remove 成功(除非文件在 Word 或其他软件中打开)

请注意,shutil 作者鼓励您复制和改进功能。 shutil.move:

文档中的注释

A lot more could be done here... A look at a mv.c shows a lot of the issues this implementation glosses over.

如果您不想修改 shutil,您可以 运行 对源文件进行递归 chmod 以确保 shutil.move 可以工作,因为像这样的实例:

for root, dirs, files in os.walk(path):  
  for f in dirs+files:  
    os.chmod(os.path.join(root, f), 0o777)

您还可以使用 shutil.copytree 然后是 shutil.rmtree 的修改版本(因为您 知道 源和目标不在同一个文件系统上)