shutil.copytree 用 copy() 维护元数据

shutil.copytree with copy() maintains Metadata

我正在尝试将目录复制到新位置。当它到达新位置时,我希望新目录的最后修改日期是它被复制到新位置的时间。

查看文档(https://docs.python.org/3/library/shutil.html 我正在使用 python 3.6),shutil.copytree 采用参数 "copy_function",默认情况下为 "shutil.copy2",因此维护大多数元数据(如修改日期)。但是将其更改为 "shutil.copy" 即:

shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=shutil.copy, ignore_dangling_symlinks=False)

似乎仍保留原始文件的修改日期。尽管根据文档 shutil.copy() 不应维护超出文件权限的元数据。

有趣的是,观察副本的目标位置,我可以看到该目录在还原为源目录的修改日期之前暂时将其修改日期设置为当前时间。

在此先感谢您的帮助。

如果您试图阻止复制目录的元数据,这是不可避免的。 copy_function 一开始就不会为目录调用,因此更改它没有任何效果。 copytree 总是调用 copystat() on each directory in the tree, as can be seen in its source code。请注意,这不会发生在文件上,因为该函数仅在目录上递归(因此 src 指向常规文件的唯一方法是将文件作为参数传递)。

如果您真的很想完成这项工作,您可以monkey patch copystat() to do nothing, but I would hardly consider that a robust solution. It would be much safer to walk the destination directory structure and use os.utime()手动重置每个目录的修改时间。

如果您试图阻止文件的元数据被复制,我无法重现您的问题:

kevin@instance-1 ~ % mkdir foo
kevin@instance-1 ~ % mkdir foo/bar
kevin@instance-1 ~ % touch foo/bar/baz --date 19700101    
kevin@instance-1 ~ % ls -l foo/bar/baz
-rw-r--r-- 1 kevin kevin 0 Jan  1  1970 foo/bar/baz
kevin@instance-1 ~ % python3
Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import shutil
>>> shutil.copytree('./foo', './qux', symlinks=False, ignore=None, copy_function=shutil.copy, ignore_dangling_symlinks=False)
'./qux'
>>> 
kevin@instance-1 ~ % ls -l qux/bar/baz 
-rw-r--r-- 1 kevin kevin 0 Feb 23 05:04 qux/bar/baz