python中shutil模块用法介绍

参考文章地址:
https://segmentfault.com/a/1190000016689023
文章翻译了python标准库中shutil的介绍:
https://docs.python.org/zh-cn/3.7/library/shutil.html

shutil模块提供了一些针对文件和目录的高级操作,主要是拷贝、移动。对于单个文件的操作,还可参考os模块

Warning: 即使是高级别的拷贝函数(shutil.copy(),shutil.copy2())也不能拷贝所有的文件元数据。意思是:在POSIX系统中,文件所有者、属组以及ACL信息会丢失。在Windows平台上,文件所有者,ACL以及ADS(供选数据流)不会被复制。On Mac OS, the resource fork and other metadata are not used. This means that resources will be lost and file type and creator codes will not be correct.

目录及文件操作

shutil.copyfileobj(fsrc, fdst[, length])

复制file-like对象fsrc的内容到fdst,如果fdst不存在则自动创建。length表示缓冲大小,如果是负数表示直接复制,不循环遍历块中的源数据。数据默认按块读取(16 * 1024)避免不可控的内存消耗。

import shutil
shutil.copyfileobj(open("fsrc.txt", "rb"), open("fdst.txt", "wb"))
'''
with open("a.txt",'rb') as f_scr:
    with open("b.txt",'wb') as f_des:
        shutil.copyfileobj(f_scr,f_des)
'''      

shutil.copyfile(src, dst, *, follow_symlinks=True)

复制文件src的内容到dst并返回dst,如果dst不存在则自动创建。src和dst是字符串类型的路径名。
如果src和dst指向同一个文件,抛出SameFileError异常。
目标位置必须是可写的,否则将抛出OSError异常(实际抛出的PermissionError)。如果dst已经存在,则直接覆盖。特殊文件比如块设备、字符设备、管道不能使用此函数复制。

如果follow_symlinks为False且src是软链接(硬链接和软链接见上一篇文章),将创建一个新的软链接替代拷贝行为

shutil.copyfile("src.txt", "dst.txt")

shutil.copytree(source,destination)

将source路径下整个文件夹,包括里面到子文件夹和文件复制到destination路径下,如果destination文件夹已经存在,就会返回一个FileExistsError错误,说明每次执行该函数都会创建destination文件夹,所以在执行前要检查destination文件夹是否存在,后面到应用的例子中有解释。

shutil.copymode(src, dst, *, follow_symlinks=True)

复制文件src的权限位(permission bits)到dst,src和dst是字符串类型的路径名。如果follow_symlinks为False且src和dst都是软链接,将修改dst软链接文件而非源文件的权限。

此函数并非所有平台可用,如果它不能修改本地平台的软链接但又执行了相关操作,将不做任何操作直接返回None

# 修改前
-rw-r--r--. 1 root  root    96 10月 11 12:26 aa.txt
-rw-------. 1 root  root  1362 9月   6 22:07 anaconda-ks.cfg
-rw-------. 1 admin admin    0 10月 11 12:53 bb.txt
lrwxrwxrwx. 1 root  root    21 10月 11 12:58 cc.txt -> /root/anaconda-ks.cfg

>>> shutil.copymode("aa.txt", "bb.txt")
>>> shutil.copymode("aa.txt", "cc.txt")

# 修改后
-rw-r--r--. 1 root  root    96 10月 11 12:26 aa.txt
-rw-r--r--. 1 root  root  1362 9月   6 22:07 anaconda-ks.cfg
-rw-r--r--. 1 admin admin    0 10月 11 12:53 bb.txt
lrwxrwxrwx. 1 root  root    21 10月 11 12:58 cc.txt -> /root/anaconda-ks.cfg

shutil.copystat(src, dst, *, follow_symlinks=True)

复制src的权限位、最后访问时间、最后修改时间以及标志(flag)到dst,src和dst是字符串类型的路径名,可以是文件或目录。在Linux平台上还会复制扩展属性。

如果follow_symlinks为False,且src和dst都是软链接,此函数直接操作软链接而非源文件(目录)。

Note:并非所有平台都能检查和修改软链接,python能告诉用户本地平台可使用哪些功能。

  • 如果os.chmod in os.supports_follow_symlinks为True,copystat()可以修改软链接的权限位
  • 如果os.utime in os.supports_follow_symlinks为True,copystat()可以修改软链接的最后访问时间和最后修改时间
  • 如果os.chflags in os.supports_follow_symlinks为True,copystat()可以修改软链接的flag
    copystat()总是能成功执行,即使是在某些它的部分或全部功能不可用的平台上修改软链接,它将最大限度地拷贝它能拷贝的所有信息。

shutil.copy(src, dst, *, follow_symlinks=True)

复制文件src的内容和权限位到dst,dst可以是文件或目录,如果是文件,函数的返回值就是dst,如果是目录,函数的返回值就是src的文件名与dst的路径拼接。src和dst都是字符串类型,如果dst指向一个目录,则创建与src同名(basename)的新文件。

如果follow_symlinks为False,且src是软链接,dst将作为软链接创建;如果follow_symlinks为True,src为软链接,则实际拷贝的是src指向的源文件。

copy()使用copymode()拷贝权限位,使用copyfile()拷贝文件内容

>>> shutil.copy("src.txt", "dst.txt")
'dst.txt'
>>> shutil.copy("src.txt", "/tmp/")
'/tmp/src.txt'
>>> shutil.copy("src.txt", "/Dota2/")     # 传入一个不存在的目录
Traceback (most recent call last):
  ...
IsADirectoryError: [Errno 21] Is a directory: '/Dota2/'

shutil.copy2(src, dst, *, follow_symlinks=True)

除了还会保留src的所有元数据(如创建时间、修改时间等),其他与copy()相同。
当follow_symlinks为False且src为软链接时,dst将作为软链接被创建并拷贝src的所有元数据到dst。
copy2()使用copystat()拷贝元数据,使用copyfile()拷贝文件内容

应用:

'''
开发环境:win10
开发工具:pycharm /python3.7
'''
from shutil import *
from pathlib import *
import re
#或者from pathlib impor WindowsPath
#或者from pathlib impor Path

#注意在同一个文件夹下面才能写成这种相对地址,否则请写文件的绝对地址
pathFile = Path('src.txt')

#打开文件src.txt,注意readlines()返回的是包含所有路径的 列表
with pathFile.open() as f:
    pathlist = f.readlines()

newpath = Path.cwd()/'src/VW'

for i in pathlist:
    #易错,千万要注意
    #因为列表元素都是地址,后面都是换行符结尾,后面使用时会将换行符也算做地址
    #就会出现错误提示:OSError:[WinError 123]  文件名,目录名,或卷标语法不正确。
   # source = i.replace('/n','')
   source = re.sub(r'(\s+?)$',",i)#用正则表达式将结尾处/t,/n,/r全部替换移除
   usource = source.encode('utf-8')#将路径统一转为utf-8编码,防止路径中包含中文乱码
    relativepath = Path(source).relative_to(Path(source).parent.parent)
    
    destipath = newpath/relativepath
    #或者destipath = newpath.joinpath(relativepath)
    #但千万不能用‘+’拼接,会报错:TypeError: unsupported oprand type(s)
    #for + :'WindowsPath' and 'WindowsPath' 

    if not destipath.exists():#这里必须判断destipath是否已经存在
        #因为执行copytree函数会自动创建一个新文件夹(根据destination参数)并将source文件夹中的内容
        #复制过去,现在在循环里面,每执行一次copytree函数会自动创建一个新文件夹
        # 就会返回一个FileExitsError错误
        copytree(usource.decode('utf-8,destipath)#将路径解码为utf-8字符串,复制文件夹

你可能感兴趣的:(Python)