Errno 22 with Python shutil and .move() function



好吧,所以我下午的大部分时间都在调试它,我正在认输。

我正在尝试创建一个系统,该系统将有助于在我的学生工作者完成工作文件夹后自动将工作文件夹放回服务器上。到目前为止,我已经记下了所有内容 - 它正确识别了匹配的服务器文件夹,并且能够在我复制新作品时将服务器文件夹移动到存档文件夹中以临时备份它。

然而,正是最后一点支撑着我。一切都运行良好,直到我到达将作为参数传递的文件夹复制回服务器的部分。

这是有问题的代码段:

print "Match Source: " + match_src
archive_folder_name = match_src.rsplit('/', 1)[1]
print "Archive Folder Name: " + archive_folder_name
if not (os.path.isdir(os.path.join(os.path.dirname(match_src), "Archive"))):
    os.mkdir(os.path.join(os.path.dirname(match_src), "Archive"))
archive_dst = os.path.join(os.path.join(os.path.dirname(match_src), "Archive"), archive_folder_name)
print "Archived Folder Destination: " + archive_dst
# okay, archive folder has been made. Now we need to move the old
# stuff to this folder.
shutil.move(match_src, archive_dst)
# okay, archive folder is filled. Now to move the new stuff there
print "Updated Source: " + updated_folder_path
print "Destination: " + os.path.dirname(match_src)
shutil.move(updated_folder_path, os.path.dirname(match_src))

以下是这些打印语句的输出和错误代码:

ServerReturn mwl36$ python serverreturn_main.py /Users/mwl36/Desktop/Week 1 
I'm on a Mac.
Path: /Users/mwl36/Desktop/Week 1
Folder: Week 1
Match Source: /Volumes/GCPSX Mac HD/ID/Marisa/Work for Student Workers/201315/SERVERTEST/Week 1
Archive Folder Name: Week 1
Archived Folder Destination: /Volumes/GCPSX Mac HD/ID/Marisa/Work for Student Workers/201315/SERVERTEST/Archive/Week 1
Updated Source: /Users/mwl36/Desktop/Week 1
Destination: /Volumes/GCPSX Mac HD/ID/Marisa/Work for Student Workers/201315/SERVERTEST
Traceback (most recent call last):
  File "serverreturn_main.py", line 124, in <module>
    main()
  File "serverreturn_main.py", line 117, in main
    shutil.move(updated_folder_path, os.path.dirname(match_src))
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 296, in move
    copytree(src, real_dst, symlinks=True)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 206, in copytree
    raise Error, errors
shutil.Error: [('/Users/mwl36/Desktop/Week 1/testfile.txt', '/Volumes/GCPSX Mac HD/ID/Marisa/Work for Student Workers/201315/SERVERTEST/Week 1/testfile.txt', "[Errno 22] Invalid argument: '/Volumes/GCPSX Mac HD/ID/Marisa/Work for Student Workers/201315/SERVERTEST/Week 1/testfile.txt'")]

我哪里出错了?如果调用 do shutil.move(src, dst) 第一次工作没有问题,为什么它在这里吠叫?我尝试在初始调用后添加延迟,但没有效果。

编辑:更奇怪的是,它实际上会执行移动,但似乎永远不会删除桌面上的旧文件夹。实质上,它将文件夹复制到 DST 位置,但不会自行清理。

编辑#2:调用os.listdir显示目录已消失,并且在第二次移动调用之前唯一的东西是"存档"。明天我在工作时将测试 copy() 并再次访问代码。

shutil.move()会将源复制到目标,然后在无法进行"简单移动"时删除源。 例如,当源和目标不在同一文件系统上时,可能会发生这种情况。

在这种情况下,shutil.move()就是这样做的:首先将源复制到目标,然后对源执行rmtree()

在复制过程中,shutil将复制源文件的字节,然后复制"统计"信息(权限、修改时间等)。 因此,似乎[Errno 22] Invalid argument要么来自复制字节,要么来自复制统计信息数据。 复制字节似乎不太可能导致EINVAL错误,因此最可能的解释是复制"stat"数据导致了此错误。

您可以通过在主脚本的开头添加类似以下内容来测试这一点:

import shutil
import sys
import traceback
orig_copystat = shutil.copystat
def my_copystat(src, dst):
    try:
        orig_copystat(src, dst)
    except Exception as e:
        sys.stdout.write('copystat failed: %sn' % e)
        traceback.print_exc()
shutil.copystat = my_copystat
# Your script here...

如果我的猜测是正确的,您将在运行脚本时看到copystat failed: ...消息(和堆栈跟踪),否则它应该"工作"。 如果您看到来自上述函数的错误消息,则可以将上述函数更改为静默忽略异常并运行脚本。 否则,请尝试如上所述的猴子修补shutil.copyfile,看看copyfile()中引发异常的确切位置。

最新更新