带有copy()的shutil.copytree维护元数据

时间:2018-02-23 03:46:11

标签: python shutil

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

查看文档(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()不应该根据文档维护超出文件权限的元数据。

有趣的是,在查看副本的目的地时,我可以看到该目录暂时将其修改日期设置为当前时间,然后再恢复为源目录的修改日期。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

如果您试图阻止目录复制其元数据,这是不可避免的。首先不会为目录调用copy_function,因此更改它不起作用。 copytree总是在树中的每个目录上调用copystat(),如in its source code所示。请注意,对于文件不会发生这种情况,因为该函数仅对目录进行递归(因此src指向常规文件的唯一方法是将文件作为参数传递。)

如果你真的非常渴望能够做到这一点,你可以monkey patch copystat()什么都不做,但我几乎不认为这是一个强有力的解决方案。 walk目标目录结构会更加安全,并使用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