Python文件管理利器之Shutil库详解

       Shutil是一个Python内置的用来高效处理文件和目录迁移任务的库。Shutil不仅支持基本的文件复制、移动和删除操作,还具备处理大文件、批量迁移目录、以及跨平台兼容性等特性。通过使用Shutil,我们可以更加轻松地实现文件系统的管理和维护,本文我将讲解该库的使用方法以需要注意的地方。

目录

 StrPath与BytesPath

 文件元数据(MetaData)

基础元数据

 时间戳元数据

 权限元数据 

系统级元数据 

符号链接

符号链接基本含义

什么时候用符号链接 

复制文件

shutil.copy

可能出现的错误

shutil.copyfile

可能出现的错误

shutil.copy2

可能出现的错误

移动文件

shutil.move

可能出现的错误:

删除目录 

shutil.rmtree

总结:

 StrPath与BytesPath

        在使用shutil内置的函数时,部分函数观察其注释可以发现传入的路径参数有两种。分别是字符串路径StrPath与BytesPath,这里我们来讲一下二者的区别。

BytesPath是路径的二进制表示形式,通常用于:

  • 处理 ​非 UTF-8 编码的文件名​(如某些特殊字符或非标准编码的文件系统)
  • 与底层操作系统 API 交互时(某些系统调用需要二进制格式的路径)

其实就是字符串的字节码,我们可以使用encode函数来将一个字符串转换为字节码

StrPath=r"E:\Desktop\lec01.pptx"
print(StrPath)
BytesPath=r"E:\Desktop\lec01.pptx".encode('utf-8')#utf-8是通用的编码方式
print(BytesPath)

对于纯英文路径来说将encode为字节码之后,即变为Bytes型路径后其输出结果为:b‘原路径’

当路径中含有非英文单词时,将其encode为字节码之后, 即变为Bytes型路径后其输出结果:

中文字符课程被encode为utf- 8类型的字节码是'\xe8\xaf\xbe\xe7\xa8\x8b',其余部分保持不变

 文件元数据(MetaData)

        文件元数据是描述文件属性的数据,包含除文件内容本身外的所有信息。在Windows系统中可以通过右键文件点击属性在属性面板中查看

基础元数据

元数据类型说明查看方法(Python)
文件名文件的名称os.path.basename(filepath)
文件大小文件的字节大小os.path.getsize(filepath)
文件类型文件扩展名/格式os.path.splitext(filepath)[1]
文件路径文件的完整存储路径os.path.abspath(filepath)

 时间戳元数据

时间戳类型说明Unix对应字段Windows对应字段
创建时间(ctime)文件创建时间st_ctimest_ctime
修改时间(mtime)文件内容最后修改时间st_mtimest_mtime
访问时间(atime)文件最后被访问时间st_atimest_atime
元数据修改时间文件属性(非内容)最后修改时间(Unix特有)st_ctime-

 权限元数据 

权限类型说明Unix查看Windows查看
文件模式读写执行权限(rwx)stat.st_mode文件属性→安全选项卡
用户ID(UID)文件所有者IDstat.st_uid-
组ID(GID)文件所属组IDstat.st_gid-
访问控制列表(ACL)更精细的权限控制getfacl命令文件属性→安全→高级

系统级元数据 

元数据类型说明查看方法
设备ID文件所在的设备标识符stat.st_dev
inode编号文件系统索引节点号(Unix)stat.st_ino
硬链接数指向该文件的硬链接数量stat.st_nlink
文件系统标志文件特殊属性(如只读、隐藏等)stat.st_flags(Unix)

上述表格中提到的元数据都可以使用os库来查看,具体代码如下: 

import os
from datetime import datetime
s=os.stat(r'BG.py')
print("="*50)
print(f"大小: {s.st_size} 字节")
print(f"设备: {s.st_dev}")
print(f"inode: {s.st_ino}")
print(f"硬链接数: {s.st_nlink}")
print(f"权限: {oct(s.st_mode)}")
print(f"所有者UID: {s.st_uid}")
print(f"所属组GID: {s.st_gid}")
print(f"创建时间: {datetime.fromtimestamp(s.st_ctime)}")
print(f"修改时间: {datetime.fromtimestamp(s.st_mtime)}")
print(f"访问时间: {datetime.fromtimestamp(s.st_atime)}")

        当然,shutil某些函数在对文件复制操作时也会涉及到对上述元数据的操作。

符号链接

     在使用shutil的一些函数时,大家可能会看到follow_symlinks类似的参数,这里的symlinks指的是符号链接,所谓符号链接(Symbolic Link,也叫软链接)就像电脑里的"快捷方式"或"替身",但它比普通的快捷方式更强大。

符号链接基本含义

        使用一个不恰当的比喻, 符号链接其实就像是个书签 📖。

        想象你在看一本很厚的书,你在第1页写了个笔记:"重要内容见第500页"。那么这个笔记其实就是一个符号链接:

  • 实际文件​ = 第500页的内容
  • 符号链接​ = 第1页的这个笔记
    你通过这个"笔记"能直接找到真正的内容

   他的特点就是:

  • 文件大小很小(就像书签只占一点点位置)
  • 删除符号链接不会影响原文件(撕掉书签不会删除第500页)

 这实际与我们安装应用时创建的快捷方式类似,当然二者还是有一些区别的,以下是二者的区别:

特性符号链接普通快捷方式
系统层级文件系统级别应用级别
兼容性所有程序都能识别部分程序识别
跨设备可以指向网络位置通常只能本地

什么时候用符号链接 

  1. 节省空间​:同一个大文件需要在多个位置使用

    比如:你的电影库实际存放在D盘,但在C盘的"我的影片"文件夹里创建链接

  2. 版本切换​:快速切换不同版本软件

    比如:python 链接可以指向 python3.8 或 python3.9

  3. 系统维护​:不改动原有结构的情况下调整文件位置

复制文件

当我们使用shutil复制文件时,共有以下函数可以用来复制文件,他们的主要作用如下表所示:

函数名称功能描述
shutil.copy(src, dst)复制文件到目标路径dst可以是目录或新文件名),​不保留文件元数据
shutil.copyfile(src, dst)仅复制文件内容,dst必须是完整文件名且不能已存在,否则报错
shutil.copytree(src, dst)递归复制整个目录树​(包括子目录),要求目标目录dst必须不存在
shutil.copy2(src, dst)功能同copy(),但会保留文件元数据​(如修改时间、权限等)
shutil.copymode(src, dst)仅复制文件的权限模式​(不复制内容或元数据)
shutil.copyfileobj(fsrc, fdst)文件对象级别复制内容(需手动打开文件对象)
shutil.copystat(src, dst)仅复制文件的元数据​(权限、时间戳等),​不复制文件内容

shutil.copy

参数详解:

参数含义类型
src待复制的源文件路径字符串或Bytes字节码路径(必须是文件名)str or bytes str
dst目标路径的字符串或Bytes字节码路径(可以是文件夹也可以是文件名)str or bytes str
follow_symlinks复制符号链接指向的实际文件内容还是复制符号链接本身bool

代码:

        需要注意的是shutil.copy只会复制文件内容,并不复制元数据,像修改时间等这些元数据都是运行代码后产生的

src路径下文件:

import os
import shutil
shutil.copy(src=r"E:\Desktop\文件保存\26162605op6m.pdf",dst=os.getcwd())

运行代码后dst路径下文件: 

可以看到最近修改时间变成了实际运行代码时间 

可能出现的错误

Permission Error(dst路径下的文件已被打开):

      需要注意的是当dst路径是文件且该文件已经被打开再尝试使用copy函数时,会出现Permission Error

dst路径下的文件已被打开,出现Permission Error异常

shutil.copyfile

        shutil.copyfile与shuitl.copy函数唯一不同的地方在于它的dst路径必须是文件名,而shutil.copy则既可以是目录名也可以是文件名。这里dst路径下的文件名的内容空白或名字重复无所谓。当然,shutil.copyfile函数也只会复制文件内容,并不复制元数据,像修改时间等这些元数据都是运行代码后产生的。

参数详解:

参数含义类型
src待复制的源文件路径字符串(必须是文件名)str
dst目标路径的字符串(必须是文件名且不能已存在)str 
follow_symlinks复制符号链接指向的实际文件内容还是复制符号链接本身bool

代码:

src路径下文件:

import os
import shutil
#选择移动到当前工作目录下
dst=os.path.join(os.getcwd(),"小谢的selenium操作手册.docx")
shutil.copyfile(src=r"E:\Desktop\测试开发\小谢的selenium操作手册.docx",dst=dst)

运行代码后dst路径下文件: 

可以看到最近修改时间变成了实际运行代码时间 

可能出现的错误

 Permission Error(dst路径下的文件已被打开):

      需要注意的是当dst路径下的文件已经被打开再尝试使用copyfile函数时,会出现Permission Error。

dst路径下的文件已被打开,出现Permission Error异常

shutil.copy2

        shutil.copy2函数的参数与shutil.copy完全一致,二者唯一的区别是shutil.copy2会一同复制元数据。

 参数详解:

参数含义类型
src待复制的源文件路径字符串或Bytes字节码路径(必须是文件名)str or bytes str
dst目标路径的字符串或Bytes字节码路径(可以是文件夹也可以是文件名)str or bytes str
follow_symlinks复制符号链接指向的实际文件内容还是复制符号链接本身bool

代码:

src路径下文件:

import os
import shutil
#选择移动到当前工作目录下
dst=os.path.join(os.getcwd(),"小谢的selenium操作手册.docx")
shutil.copy2(src=r"E:\Desktop\测试开发\小谢的selenium操作手册.docx",dst=dst)

运行代码后dst路径下文件: 

元数据一模一样(这里只看修改时间便可以看出)。 

可能出现的错误

Permission Error(dst路径下的文件已被打开):

      需要注意的是当dst路径是文件且该文件已经被打开再尝试使用copy函数时,会出现Permission Error。

dst路径下的文件已被打开,出现Permission Error异常

 shutil.copytree

        shutil.copytrees是用来将一个文件夹下的所有内容复制到另一个文件夹中的函数。

参数详解:

参数名称功能描述
src必需参数,表示源目录的路径(字符串类型)。
dst必需参数,表示目标目录的路径(字符串类型)。
symlinks可选参数,布尔值(默认为 False)。若为 True,则复制符号链接本身;若为 False,则复制链接指向的实际内容。
ignore可选参数,可指定一个函数(如 shutil.ignore_patterns),用于过滤不需要复制的文件或目录。
copy_function可选参数,指定用于复制的函数(默认为 shutil.copy2,保留元数据)。也可替换为 shutil.copy 等。
ignore_dangling_symlinks可选参数,布尔值(默认为 False)。若为 True,则跳过无效的符号链接而不抛出异常。
dirs_exist_ok可选参数,布尔值(默认为 False)。若为 True,允许目标目录已存在(Python 3.8+ 新增)。

代码:

src路径下文件:

import shutil
'''
dir_exist_ok设置为True,
此时无论dst路径下的文件夹是否存在
都将被复制到dst路径下的文件夹内
'''
shutil.copytree(src=r"E:\Desktop\Videos",dst=r"E:\Desktop\test",dirs_exist_ok=True)

可能出现的错误

 NotADirectoryError(src路径下的内容非文件夹)

当src路径下的内容不是文件夹时会产生这个错误

 FileExitsError(dst下的文件夹已存在)

        dst路径下的文件夹存在且dir_exists_ok参数未设置为True,会产生这个错误

移动文件

shutil.move

参数详解:

参数含义类型
src待复制的源文件字符串(可以是文件名也可以是文件夹)str 
dst目标路径的字符串(可以是文件名也可以是文件夹)str
copy_funciton复制文件回调函数,默认是shuti.copy2callable

        需要注意的是src是文件夹时,dst也必须是一个文件夹,因为我们不能把一个文件夹移动到一个文件里去。

代码: 

import os
import shutil
shutil.move(src=r"E:\Desktop\文件保存\.docx",dst=os.getcwd())

        关于copy_function这一参数的说明:

shutil.move函数文档注释内容 

        所谓移动文件其实就是先把文件复制到目标路径下,然后再把原路径下的文件删除。而将文件复制到目标路径下这一功能无非就是使用shutil.copy,shutil.copy2等函数来实现,正如上边注释所言:可选的 'copy_function' 参数是将要使用的可调用复制源,否则它将被委托给 'copytree'。默认情况下,使用 copy2()

可能出现的错误:

Permission Error(src路径下的文件已被打开):

        在任何操作系统上我们都无法对一个已经被打开的文件进行迁移操作,如果src路径下的文件被打开,那么自然也会抛出PermissionError的错误。

Error(dst路径下已经有一个与src传入路径下同一个basename的文件)

dst路径下有一个名为test.docx的文件

提示test.docx already exists 

ErrorCannot move a directory into itself) :

        当src与dst二者存在包含关系,且src为父目录时,便会产生这个错误。这里,文件保存是Desktop内的一个文件夹,当我们尝试将Desktop移动到这个文件夹时便会出现这个错误。

FileExitsError(src路径为文件夹,dst下的路径为文件时)

        src是一个文件夹,dst是一个文件,当我们尝试将一个文件夹移动到文件中时便会产生错误

删除目录 

        shutil.rmtree是shutil模块中唯一用来执行删除功能的函数,当然可以用来删除文件的函数还有很多,比如os模块下的os.remove,os.rmdir,下表给出了这几三者之间的区别:

函数能删文件能删空目录能删非空目录适用场景
shutil.rmtree()❌ 不能✔️ 可以✔️ 可以仅用于删除目录树(彻底删除内部所有文件夹及内容)
os.remove()✔️ 可以❌ 不能❌ 不能仅用于删除单个文件
os.rmdir()❌ 不能✔️ 可以❌ 不能仅用于删除空目录

shutil.rmtree

参数详解:

参数类型默认值功能描述
pathstr必填要删除的目录路径,需要注意的是路径必须是目录且不为空
ignore_errorsboolFalse是否忽略删除过程中可能产生的各种错误
onerrorcallableNone错误处理回调函数
dir_fdintNone目录文件描述符(仅Unix)
onexc (Python 3.12+)callableNone异常处理回调函数(新版替代

在该文件夹下,我创建了3层深度的文件夹,并在内部新建了一个txt类型文件 

代码 :

import shutil
shutil.rmtree(r"E:\Desktop\rmtree测试",ignore_errors=True)

运行代码后,该文件夹被彻底删除!但是os.remove和os.remdir对此却无能为力

总结:

        shutil是一个python内置的用来进行文件迁移的模块,该模块本质上是对os模块处理文件相关操作的二次开发,比如shutil.copyfile函数,其实就是在使用with open语句进行两次io操作:先读取src内容,再将读取内容写入到dst路径。

        类似这样的操作我们自己也可以写出来,只不过并不一定会考虑到各种可能存在的异常情况以及跨平台兼容性等问题,而shutil则已经将这些情况全部考虑并封装成为了‘’轮子‘’供我们直接调用,快捷而方便。当然,这也是Python的特色之一。

        我想要驾驶一辆汽车,难道还需要自己制造轮胎吗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/910331.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/910331.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习华为 ensp 的学习心得体会

引言​ 在信息技术日新月异的今天,网络技术作为连接世界的桥梁,其重要性不言而喻。作为一名对网络技术充满热情的大一新生,我选择了 eNSP(Enterprise Network Simulation Platform,企业网络模拟平台)作为我…

jenkins-2.439.1搭建

一、 二、pipeline文件 pipeline { agent any // 可以指定特定的agent, 如 label 或 docker environment { JAVA_HOME "/usr/local/software/jdk1.8.0_451" PATH "${JAVA_HOME}/bin:${env.PATH}" } tools { …

【threejs】一天一个小案例讲解:控制面板(GUI)

# 好吧,每天更新实在有点艰巨,我尽量少量多次 代码仓 所有代码都会上传到这里,可自行clone GitHub - TiffanyHoo/three_practices: Learning three.js together! 运行效果图 ​ 知识要点 一、安装dat.gui npm i dat.gui 二、使用步骤&a…

飞轮储能辅助双馈风机参与电力系统一次调频的仿真模型研究

以下是一篇关于飞轮储能辅助双馈风机参与电力系统一次调频的仿真模型研究的论文 ,涵盖理论分析、数学模型构建、控制策略设计及仿真验证等内容,适用于电气工程、新能源技术等领域的研究参考。 飞轮储能辅助双馈风机参与电力系统一次调频的仿真模型研究 摘要 随着风电在电力…

一次性理解Java垃圾回收--简单直接方便面试时使用

Java的垃圾回收是一个面试必问题,只要按照下面的步骤回答肯定不会有大问题。 1.先告诉面试官垃圾回收分为两大步: a.识别哪些对象是"垃圾"(不再被使用的对象) b.回收这些垃圾对象占用的内存空间 2. 接下来分别介绍标记阶段和回收阶段的细节…

XML映射文件-辅助配置

如果你没有按照同包同名来,就要下面的配置,指定好路径 1.把路径改为类下面的xml文件 #指定xml映射文件的位置 mybatis.mapper-locationsclasspath:mapper/*.xml

120、三角形最小路径和

题目 解答: 直接按照空间复杂度O(n)来做了。这种明显是动态规划,每一层用到上一层的信息。 观察数据形状,如下: (0,0) (1,0)(1,1) (2,0)(2,1)(2,2) (3,0)(3,1)(3,2)(3,3) ... (n-1,0)...(n-1,n-1) 设dp[n],定义为本层第n…

仕么是Transformer以及工作原理和架构

Transformer 是一种革命性的**深度学习架构**,由 Google 团队在 2017 年论文《Attention is All You Need》中提出。它彻底改变了自然语言处理(NLP)领域,并逐渐扩展到计算机视觉、语音识别等多模态任务。其核心创新在于**完全依赖…

opencv 锁页内存的使用

在OpenCV的CUDA编程中,cv::cuda::HostMem类用于管理锁页内存(Page-Locked Memory)​,这种内存能显著提升主机(CPU)与设备(GPU)间的数据传输效率。而.createMatHeader()正是将HostMem…

亚远景-ASPICE与ISO 26262:理解汽车软件质量保障的双标体系

在汽车行业向智能化、电动化转型的背景下,ASPICE(Automotive SPICE)与ISO 26262作为汽车软件质量保障的两大核心标准,分别从过程能力与功能安全两个维度构建了完整的开发管理体系。以下从标准定位、核心差异、协同实践及行业价值四…

数组的应用

Java数组的基本概念 数组是Java中一种重要的数据结构,用于存储固定大小的相同类型元素。数组在内存中连续分配空间,可以通过索引快速访问元素。数组的声明和初始化是使用数组的基础,声明时需要指定数据类型和数组名称,初始化可以…

基础RAG实现,最佳入门选择(七)

增强型RAG系统的查询转换 采用三种查询转换技术,以提高RAG系统中的检索性能,而无需依赖于像LangChain这样的专门库。通过修改用户查询,我们可以显著提高检索信息的相关性和全面性。 关键转换技术 1.查询重写:使查询更加具体和详…

企业应用观测中枢建设

本文来自腾讯蓝鲸智云社区用户: CanWay 运维挑战加剧 新时代技术背景下,运维面临的挑战加剧: 1、业务数量日益增加、业务规模日益庞大 随着科技发展进步、民众生活富足,线下业务线上化、线上业务复杂化趋势愈演愈烈,各行各业投…

Python实例题:基于边缘计算的智能物联网系统

目录 Python实例题 题目 问题描述 解题思路 关键代码框架 难点分析 扩展方向 Python实例题 题目 基于边缘计算的智能物联网系统 问题描述 开发一个基于边缘计算的智能物联网系统,包含以下功能: 边缘设备管理:连接和管理大量物联网…

一,python语法教程.内置API

一,字符串相关API string.strip([chars])方法:移除字符串开头和结尾的空白字符(如空格、制表符、换行符等),它不会修改原始字符串,而是返回一个新的处理后的字符串 chars(可选)&…

私有 Word 文件预览转 PDF 实现方案

私有 Word 文件在线预览方案(.doc/.docx 转 PDF) 前言 由于 .doc 和 .docx Word 文件 无法在浏览器中直接预览(尤其在私有 API 场景下),常见的 Content-Disposition: inline 并不能生效。因此,本方案通过…

Alpine Docker 容器中安装包缓存与 C/C++ 运行问题

在使用 Docker 容器部署应用时,基于 Alpine 镜像能带来轻量化的优势,但过程中也会遇到不少问题。今天就来分享下我在 Alpine 容器中解决安装包缓存与 C/C 程序运行问题的经验。 一、Alpine 安装包缓存到本地目录 Alpine Linux 默认使用apk作为包管理工…

[2-02-02].第59节:功能函数 - 函数基础

服务器端操作学习大纲 一、函数基础 需求场景 在shell脚本的编写过程中,我们经常会遇到一些功能代码场景:多条命令组合在一起,实现一个特定的功能场景逻辑、一些命令在脚本内部的多个位置频繁出现。在这些场景的代码量往往不多,…

RA4M2开发涂鸦模块CBU(6)----RA4M2驱动涂鸦CBU模组

RA4M2开发涂鸦模块CBU.6--RA4M2驱动涂鸦CBU模组 概述视频教学样品申请参考程序硬件准备接口生成UARTUART属性配置R_SCI_UART_Open()函数原型回调函数user_uart_callback0 ()变量定义按键回调更新按键状态DP-LED 同步长按进入配网涂鸦协议解析主循环任务调度 概述 本方案基于瑞…

MiniMax-M1: Scaling Test-TimeCompute Efficiently with I Lightning Attention

我们推出了MiniMax-M1,这是全球首个开源权重、大规模混合注意力推理模型。MiniMax-M1采用了混合专家系统(Mixture-of-Experts,简称MoE)架构,并结合了闪电注意力机制。该模型是在我们之前的MiniMax-Text-01模型&#xf…