python文件拷贝 --- shutil
shutil
shutil库提供了进行文件拷贝的方法。打开两个文件,从一个文件读取,写入另一个文件中,实现文件内容的拷贝。
这种拷贝是对文件内容的拷贝,没有拷贝文件的元数据信息,这样丢失了文件的 stat 数据:例如权限,time等。可以通过系统调用,获取原文件得元数据信息,再将新文件的元数据信息更改为一致即可。部分元数据信息需要有足够的权限,属主或者属组等信息需要root权限。
shutil的方法
1.文件和目录的拷贝。copy 系列的方法
2.文件和目录的打包压缩。pack / archive 系列的方法
__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", "copytree", "move", "rmtree", "Error", "SpecialFileError", "ExecError", "make_archive", "get_archive_formats", "register_archive_format", "unregister_archive_format", "get_unpack_formats", "register_unpack_format", "unregister_unpack_format", "unpack_archive", "ignore_patterns", "chown", "which", "get_terminal_size", "SameFileError"]
- shutil.copyfileobj()
shutil.copyfileobj(fsrc, fdst, [length])
fsrc,fdst 是源和目标的文件对象
def copyfileobj(fsrc, fdst, length=16*1024): while 1: buf = fsrc.read(length) if not buf: break fdst.write(buf) def _samefile(src, dst): # Macintosh, Unix. if hasattr(os.path, 'samefile'): return os.path.samefile(src, dst) # 通过文件名比较两个文件路径是否相同,相同返回True return (os.path.normcase(os.path.abspath(src)) == os.path.normcase(os.path.abspath(dst)))
- shutil.copyfile()
copyfile(src, dst, *, follow_symlinks=True)
src, dst 是路径名,必须存在,否则报错,也可以直接使用pathlib.Path对象
src 如果是文件symlink 取决于follow_symlinks,为True拷贝源文件,False拷贝链接
最终调用copyfileobj()拷贝
- copymode
def copymode(src, dst, *, follow_symlinks=True) os.chmod(dst, stat.S_IMODE(os.stat(src).st_mode)), 第二个参数验证权限? 调用os.chmod方法拷贝权限信息 symlink文件调用os.lchmod(),系统没有提供这个方法直接返回None,不做更改
- copystat
copystat(src, dst, *, follow_symlinks=True) Copy all stat info (mode bits, atime, mtime, flags) from src to dst copystat 也会拷贝 mode信息 os.chmod(dst, mode,) 设置权限 os.utime(dst, time=(atime,mtime), ns=(atime_ns, mtime_ns)) 设置时间
- copy
copy(src, dst, *, follow_symlinks=True) dst是目录在下面创建src同名文件拷贝,不是目录直接拷贝 调用copyfile和copystat return dst copy 和 copy 只是拷贝元数据不同,拷贝的内容操作相同
- copytree
copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False) 拷贝整个目录树,dst必须不存在,否则直接报错, ignore = 一个函数func(src, fnames),将这个fnames中不拷贝的文件放入一个集合返回,拷贝的时候会跳过(ignore)集合中的文件, copy_function:选择使用shutil.copy 还是 shutil.copy2,两种拷贝方式 该目录中如果存在link文件,会找到源文件,创建一个link指向源文件
copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False) names = os.listdir(src) if ignore is not None: ignored_names = ignore(src, names) #需要自己提供的ignore函数 else: ignored_names = set() # 忽略为空 os.makedirs(dst) # 创建目标目录,要求目标必须不存在 for name in names: if name in ignored_names: continue srcname = os.path.join(src, name) dstname = os.path.join(dst, name) if os.path.islink(srcname): # 如果是link文件 linkto = os.readlink(srcname) # readlink 返回被src指向的文件 if symlinks: os.symlink(linkto, dstname) # 创建一个link dst -> src,即dstname -> linkto copystat(srcname, dstname, follow_symlinks=not symlinks) else: if not os.path.exists(linkto) and ignore_dangling_symlinks: continue if os.path.isdir(srcname): # 链接到目录上,再次copytree copytree(srcname, dstname, symlinks, ignore, copy_function) else: copy_function(srcname, dstname) elif os.path.isdir(srcname): # 是目录,copytree递归 copytree(srcname, dstname, symlinks, ignore, copy_function) else: # 是文件,使用指定copy函数。 copy_function(srcname, dstname)