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)

 

posted @ 2020-06-08 22:07  没有想象力  阅读(621)  评论(0编辑  收藏  举报