Python中的高级文件操作模块shutil

版权声明:qq:1263351411 https://blog.csdn.net/u013008795/article/details/89787708

高级文件操作模块shutil

常用方法

copy拷贝方法
  • copyfileobj(fsrc,fdst[,length]) #拷贝文件对象,将fsrc文件对象内容拷贝到fdst文件对象中。复制文件内容,不含元数据
    • fsrc:源文件对象,是open打开的文件对象
    • fdst: 目标文件对象,是open打开的文件对象
    • length:缓冲区buffer的大小,可选参数,默认是16*1024
    • 注意: 如果源文件是文本模式打开,目标文件一定也要是文本模式写入
    • python对应原码如下:
    def copyfileobj(fsrc, fdst, length=16*1024):
        """copy data from file-like object fsrc to file-like object fdst"""
        while 1:
            buf = fsrc.read(length)
            if not buf:
                break
            fdst.write(buf)
    
  • coypfile(src,dst,*,follow_symlinks=True) #根据文件路径,拷贝文件。复制文件内容,不含元数据。本质上是用copyfileobj对象拷贝
    • src:源文件路径,可以是Path对象或者字符串文件路径对象
    • dst:目标文件路径,可以是Path对象或者字符串文件路径对象
    • follow_symlinks = True,是否跟进链接文件。
      • True:表示拷贝链接文件所指向的文件
      • False:表示拷贝链接文件本身
    • Python中部分源码如下:
    def copyfile(src, dst, *, follow_symlinks=True):
        ##部分代码以省略##
        if not follow_symlinks and os.path.islink(src):
            os.symlink(os.readlink(src), dst)
        else:
            with open(src, 'rb') as fsrc:
                with open(dst, 'wb') as fdst:
                    copyfileobj(fsrc, fdst)
        return dst
    
  • copymode(src,dst,*,follow_symlinks=True) #仅仅复制权限
    • src:源文件路径,可以是Path对象或者字符串文件路径对象
    • dst:目标文件路径,可以是Path对象或者字符串文件路径对象
    • follow_symlinks:是否跟进链接文件。
      • True:表示拷贝链接文件所指向的文件
      • False:表示拷贝链接文件本身
  • copystat(src,dst,*,follow_symlinks=True) #拷贝文件元数据
    • src:源文件路径,可以是Path对象或者字符串文件路径对象
    • dst:目标文件路径,可以是Path对象或者字符串文件路径对象
    • follow_symlinks:是否跟进链接文件。
      • True:表示拷贝链接文件所指向的文件
      • False:表示拷贝链接文件本身
  • copy(src,dst,*,follow_symlinks=True) #复制文件内容和权限已经部分元数据,不包括创建和修改时间。
    • 本质上是调用的copyfile,和copymode
    • src:源文件
    • dst: 目标文件路径
    • follow_symlinks: 是否跟进链接文件
  • copy2(src,dst,*,follow_symlinks=True) #比copy多了复制全部元数据,但需要平台支撑。
    • 本质上调用的是copyfile,copystat
    • src:源文件
    • dst: 目标文件路径
    • follow_symlinks: 是否跟进链接文件
  • copytree(src,dst,symlinks=False,ignore=None,copy_function=copy2,ignore_dangling_symlinks=False) #递归拷贝文件
    • src:源文件路径,必须是目录,必须存在
    • dst: 目标文件路径,必须是目录,可以不是实际存在
    • symlinks: 是否拷贝链接文件本身,默认值为False 表示跟进链接文件。
      • False 拷贝链接文件所指向的文件
      • True 拷贝链接文件本身,不跟进链接文件。
    • ignore:是一个函数,提供一个callable(src,names)->ignored_names。用于过滤哪些条件的目录不需要拷贝。默认值为None表示不需要过滤,会默认生成一个空set()集合给ignored_names
      • collable(src,names)->ignored_names
        • src 源目录
        • names 是os.litdir(src)的结果,就是列出src中的文件名
        • ignored_names:要被过滤的文件名的set类型数据。
      • 原码中对应位置代码如下:
      names = os.listdir(src)
      if ignore is not None:
          ignored_names = ignore(src, names)
      else:
          ignored_names = set()
      
      os.makedirs(dst)
      errors = []
      for name in names:
          if name in ignored_names:
              continue
          pass #后面代码这里省略,可以查看python中copytree原码
      
    • copy_function:是一个函数,默认为copy2拷贝函数,拷贝时带上文件元数据信息
    • ignore_dangling_symlinks: 链接文件所指向的文件不存在,是否出现异常,默认值为False
      • False: 表示,如果有异常,正常出现
      • True: 屏蔽链接文件所指向的文件不存在出现的异常
    • 综合简单示例:
    import shutil,os
    from pathlib import Path
    h = Path("a/b/c/d")
    h.mkdir(parents=True,exist_ok=True) #创建目录
    h.parent.joinpath("e/").mkdir(parents=True,exist_ok=True)
    h.parent.joinpath("f/").mkdir(parents=True,exist_ok=True)
    names = ["a.txt","b.txt","c.txt","c2.txt","c3.txt","d.txt","b1.txt","b2.txt","a1.txt","a2.txt"]
    for i in names: #创建文件
        f = os.open(h.joinpath(i),os.O_CREAT)
        os.close(f)
        f = os.open(h.parent.joinpath(i),os.O_CREAT)
        os.close(f)
        f = os.open(h.parent.joinpath("e/",i),os.O_CREAT)
        os.close(f)
        f = os.open(h.parent.joinpath("f/",i),os.O_CREAT)
        os.close(f)
    #过滤以a开头和以c开头的文件。
    fun = lambda src,name: {*filter(lambda name: name.startswith("a") or name.startswith("c"),names)}
    #将a目录中的所有内容拷贝到b目录中
    shutil.copytree(Path("a"),Path("b"),ignore=fun)
    
rm删除方法
  • shutil.rmtree(path,ignore_errors=False,οnerrοr=None) #递归删除,如同rm -rf一样危险,慎用。肯能会出现删除错误而中断,已经删除的就删除了。
    • path:要删除的路径对象
    • ignore_errors:是否忽略删除错误。默认为False表示不忽略。
      • True 忽略删除错误
      • False 不忽略删除错误,如果出现错误就终止,不过错误之前删除的文件已经删除。
    • onerror:是个函数,与ignore_errors结合使用。调用方式为:onerror(os.lstat, path, sys.exc_info())
      • 原码部分代码如下
      if ignore_errors:
          def onerror(*args):
              pass
      elif onerror is None:
          def onerror(*args):
              raise
      # 部分代码省略
      
move移动方法
  • move(src,dst,copy_function=copy2) #移动文件或目录到目标,返回目标。
    • 本身使用的是os.rename方法。如果不支持rename方法,如果是目录就会使用copytree在删除源目录。默认使用copy2方法
    • src :源目录,或文件
    • dst :目标
    • copy_function :复制时的拷贝函数,默认为copy2
    • python源码如下:
    def move(src, dst, copy_function=copy2):
        real_dst = dst
        if os.path.isdir(dst):
            if _samefile(src, dst):
                # We might be on a case insensitive filesystem,
                # perform the rename anyway.
                os.rename(src, dst)
                return
    
            real_dst = os.path.join(dst, _basename(src))
            if os.path.exists(real_dst):
                raise Error("Destination path '%s' already exists" % real_dst)
        try:
            os.rename(src, real_dst)
        except OSError:
            if os.path.islink(src):
                linkto = os.readlink(src)
                os.symlink(linkto, real_dst)
                os.unlink(src)
            elif os.path.isdir(src):
                if _destinsrc(src, dst):
                    raise Error("Cannot move a directory '%s' into itself"
                                " '%s'." % (src, dst))
                copytree(src, real_dst, copy_function=copy_function,
                        symlinks=True)
                rmtree(src)
            else:
                copy_function(src, real_dst)
                os.unlink(src)
        return real_dst
    

猜你喜欢

转载自blog.csdn.net/u013008795/article/details/89787708