在 Python 中执行高级文件操作:shutil 模块
手动将文件或文件夹从一个目录复制或移动到另一个目录可能会很痛苦。这可以使用名为shutil.
Shutil 模块提供了一些对文件和文件集合的高级操作,如复制、移动或删除文件。
换句话说,该shutil模块有助于自动执行文件复制或从一个目录移动到另一个目录的任务。它属于 Python 标准库,因此不需要在外部安装。
在本文中,我们将学习此模块。
将文件复制到另一个目录
shutil.copy()方法用于将源文件的内容复制到目标文件或目录。虽然复制过程也会复制文件的权限模式,但不会保留文件的创建和修改时间等其他元数据。
源必须表示文件,但目标可以是文件或目录。如果目标是一个目录,那么文件将被复制到目标目录,并使用源中的基本文件名。目的地必须是可写的。
如果目标是一个文件并且已经存在,那么它将被源文件替换,否则将创建新文件。
语法: shutil.copy(source, destination, *, follow_symlinks = True)
范围:
- source:显示源文件路径的字符串。
- 目的地:一个字符串,显示目标文件或目录的路径。
- follow_symlinks(可选):此参数的默认值为 True。如果它是 False 并且源代表一个符号链接,那么目标将被创建为一个符号链接。
将源文件复制到目标
import shutil
# source and destination path
src_path = "hello.txt"
dst_path = "hello2.txt"
path = shutil.copy(src_path, dst_path)
# Printing the path of destination dir
print('Destination Path:', path)
输出
Destination Path: hello2.txt
如果目标是目录
import os
import shutil
# Making a directory
os.mkdir('Project')
# Listing the files in it
print("Empty Folder: ", os.listdir('Project'))
# source and destination path
src_path = "hello.txt"
dst_path = "Project"
# Copying file to destination
path = shutil.copy(src_path, dst_path)
# Printing the name of copied filename and path of destination dir
print('File Copied:', os.listdir('Project'))
print('Destination Path:', path)
输出
Empty Folder: []
File Copied: ['hello.txt']
Destination Path: Project\hello.txt
将元数据与文件一起复制
shutil.copy2()方法用于将源文件的内容复制到目标文件或目录。它与该方法相同,shutil.copy()但唯一的区别是该方法试图保留文件的元数据。
语法: shutil.copy2(source, destination, *, follow_symlinks = True)
范围:
- source:显示源文件路径的字符串。
- 目的地:一个字符串,显示目标文件或目录的路径。
- follow_symlinks(可选):此参数的默认值为 True。如果它是 False 并且源代表一个符号链接,那么它会尝试将所有元数据从源符号链接复制到新创建的目标符号链接。此功能取决于平台。
import os
import shutil
# Specifying src and dst paths
src_path = "Data\geek.txt"
dst_path = "NewData"
print("Before copying the metadata:")
# Listing the files inside src folder
src_folder = "Data"
print(os.listdir(src_folder))
# Printing the status of the files inside src path
print("Metadata:", os.stat(src_path), "\n")
# Copying content from src to dst
dest = shutil.copy2(src_path, dst_path)
print("After copying the metadata:")
# Listing the files inside dst path
print(os.listdir(dst_path))
# Printing the status of the files inside dst path
print("Metadata:", os.stat(dest), "\n")
# Printing the destination path of newly created files
print("Files copied to:", dest)
输出
Before copying the metadata:
['geek.txt', 'hello.py', 'python.txt']
Metadata: os.stat_result(st_mode=33206, st_ino=7036874417909405, st_dev=3836766283, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1662197106, st_mtime=1662196237, st_ctime=1662194099)
After copying the metadata:
['geek.txt']
Metadata: os.stat_result(st_mode=33206, st_ino=20547673300020899, st_dev=3836766283, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1662197106, st_mtime=1662196237, st_ctime=1662204751)
Files copied to: NewData\geek.txt
如果目标是目录
import os
import shutil
path = "NewData"
print("Before copying the files:")
# Listing the files inside dst folder
print(os.listdir(path), "\n")
# Specifying src and dst paths
src_path = "Sample/hello.txt"
dst_path = "NewData"
# Copying content from src to dst
dest = shutil.copy2(src_path, dst_path)
print("After copying the metadata:")
# Listing the files inside dst folder
print(os.listdir(path))
# Printing the destination path of newly created files
print("Files copied to:", dest)
输出
Before copying the files:
[]
After copying the files:
['hello.txt']
Files copied to: NewData\hello.txt
将内容从一个文件复制到另一个文件
shutil.copyfile()方法用于将源文件的内容复制到没有元数据的目标文件。源和目标必须代表一个文件,并且目标文件必须是可写的。如果目标已经存在,那么它将被替换或创建一个新文件。
语法: shutil.copyfile(source, destination, *, follow_symlinks = True)
范围:
- source:显示源文件路径的字符串。
- 目的地:一个字符串,显示目标文件或目录的路径。
- follow_symlinks(可选):此参数的默认值为 True。如果 False 和 source 代表一个符号链接,那么将创建一个新的符号链接而不是复制文件。
import shutil
# Specifying the src and dest file paths
src_path = "Data/python.txt"
dst_path = "NewData/geek.txt"
# Copying the src file to dst file
dest = shutil.copyfile(src_path, dst_path)
# Printing the path of newly created file
print("File Copied to:", dest)
输出
File Copied to: NewData/geek.txt
如果源文件路径和目标文件路径相同
如果发生这种情况,则会引发 SameFIleError,我们可以使用shutil.SameFileError.
import shutil
# Specifying the dst file same as src file
src_path = "Data/python.txt"
dst_path = "Data/python.txt"
try:
dest = shutil.copyfile(src_path, dst_path)
print("File Copied to:", dest)
# Printing error
except shutil.SameFileError:
print("Source and Destination represent the same file.")
输出
Source and Destination represent the same file.
复制目录树
shutil.copytree()方法用于复制完整的目录树。它递归地复制以源目录为根的整个目录树到目标目录。目标目录必须不存在。在此过程中将创建新目录。
语法: shutil.copytree(src, dst, symlinks = False, ignore = None, copy_function = copy2, ignore_dangling_symlinks = False)
范围:
- src:显示源目录路径的字符串。
- dest:显示目的地路径的字符串。
- symlinks(可选):此参数接受 True 或 False,取决于原始链接或链接链接的元数据将被复制到新树中。
- ignore(可选):如果给出了ignore,它必须是一个可调用的,它将接收copytree()正在访问的目录作为其参数,以及它的内容列表,由os.listdir()返回。
- copy_function(可选):此参数的默认值为copy2,该参数可以使用其他复制函数如copy()。
- ignore_dangling_symlinks(可选):此参数值在设置为 True 时用于在符号链接指向的文件不存在时对引发的异常设置静音。
import shutil
# Specifying src directory
src_path = "Data"
# src dir tree will be copied to the destination
dst_path = "Project"
# Copy the entire src directory tree to the destination
dest = shutil.copytree(src_path, dst_path)
print("File Copied to:", dest)
输出
File Copied to: Project
删除目录树
shutil.rmtree()方法用于删除整个目录树,指定的路径必须指向一个目录(但不能指向一个目录的符号链接)。
语法: shutil.rmtree(path, ignore_errors=False, onerror=None)
范围:
- path:表示文件路径的类路径对象。类路径对象是表示路径的字符串或字节对象。
- ignore_errors:如果ignore_errors 为真,删除失败导致的错误将被忽略。
- oneerror:如果 ignore_errors 为 false 或省略,则通过调用 onerror 指定的处理程序来处理此类错误。
删除顶级目录树
import shutil
# Directory tree to be removed
dir_to_be_removed = "Sample"
# Removing a top-level dir
remove = shutil.rmtree(dir_to_be_removed)
print("Successfully removed.")
输出
Successfully removed.
删除目录下的目录树
import shutil
import os
# Directory location
path = "Sample/NewDirectory"
# directory to be removed
dir_to_be_removed = "Python"
# joined the path
join_path = os.path.join(path, dir_to_be_removed)
# removing directory
shutil.rmtree(join_path)
print("Successfully removed.")
输出
Successfully removed.
将文件移动到另一个位置
shutil.move()方法用于将源文件或目录移动到目标位置。如果目标目录已经存在,则源目录将移动到该目录中。
语法: shutil.move(src, dst, copy_function=copy2)
范围:
- src:显示源文件路径的字符串。
- dst:一个字符串,显示目标文件或目录的路径。
- copy_function(optional):此参数的默认值为copy2。我们也可以使用其他复制功能。
import shutil
# Specifying src and dst directories
src_path = "Project"
dst_path = "NewProject"
# Moving src dir to dst dir
dest = shutil.move(src_path, dst_path)
# Printing the destination location
print("Directory moved to:", dest)
输出
Directory moved to: NewSample\Data
如果目的地不存在
import shutil
# Specifying src directory
src_path = "New_dir"
# Non-existing directory
dst_path = "Moved_dir"
# Moving src dir to dst dir
dest = shutil.move(src_path, dst_path)
# Printing the destination location
print("Directory moved to:", dest)
输出
Directory moved to: Moved_dir
查找可执行文件
shutil.which()方法用于查找cmd参数指定的可执行文件的路径。如果没有指定cmd那么它将返回None.
语法: shutil.which(cmd, mode = os.F_OK | os.X_OK, path = None)
范围:
- cmd:字符串格式的文件。
- mode:此参数指定方法应执行的模式。
- os.F_OK 测试路径是否存在
- os.X_OK 检查路径是否可以执行
- path:此参数指定要使用的路径,如果没有指定路径,则使用 os.environ() 的结果
import shutil
# Executable file to be located
exec_file = "pip"
# Finding the location
location = shutil.which(exec_file)
# Printing the location of the executable file
print(location)
输出
D:\SACHIN\Python310\Scripts\pip.EXE
更酷的方法
shutil除了上述方法之外,该模块还提供了一些其他很酷的方法。
复制文件或目录的统计信息
shutil.copystat()方法用于将文件或目录的统计信息(例如权限位、上次访问时间、上次修改时间和标志)从源复制到目标。
import shutil
import os
import time
src_path = "D:/SACHIN/Pycharm/Number-Converter"
dst_path = "D:/SACHIN/Pycharm/OpenCV/project1.py"
# Printing metadata of source dir
print("Source Data")
print("Modified at:", time.ctime(os.stat(src_path).st_mtime))
print("Accessed at:", time.ctime(os.stat(src_path).st_atime), "\n")
# Printing metadata of destination dir
print("Destination Data")
print("Modified at:", time.ctime(os.stat(dst_path).st_mtime))
print("Accessed at:", time.ctime(os.stat(dst_path).st_atime), "\n")
# Copying stats of src to dst
shutil.copystat(src_path, dst_path)
# Printing metadata after using shutil.copystat() method
print("Destination data after using shutil.stat()")
print("Modified at:", time.ctime(os.stat(dst_path).st_mtime))
print("Accessed at:", time.ctime(os.stat(dst_path).st_atime))
输出
Source Data
Modified at: Fri Jun 10 19:31:51 2022
Accessed at: Mon Sep 5 16:22:19 2022
Destination Data
Modified at: Tue Jul 27 19:00:02 2021
Accessed at: Mon Sep 5 16:23:27 2022
Destination data after using shutil.stat()
Modified at: Fri Jun 10 19:31:51 2022
Accessed at: Mon Sep 5 16:22:19 2022
检索磁盘使用情况统计信息
shutil.disk_usage(path)方法用于获取指定路径****的磁盘使用统计信息。返回值具有属性total、used和free,它们是总、已用和可用空间的数量(以字节为单位)。路径可以是文件或目录。
import shutil
# Checking the stats
disk_size = shutil.disk_usage("NewSample")
# Printing the stats
print("The stats are:", disk_size)
输出
The stats are: usage(total=374277664768, used=33221120000, free=341056544768)
归档目录
shutil.make_archive()用于创建 zip 或 tar 格式的存档文件。
import shutil
# Path of directory to be archived
directory = "NewSample"
# Archiving the directory with zip format
archive = shutil.make_archive(directory, format="zip")
print(archive)
输出
NewSample.zip
解压目录
shutil.unpack_archive()用于解压归档文件。该方法有两个参数,第一个是文件名,它是存档文件的完整路径,第二个是提取文件的目录。
import shutil
# Path of directory to be unpacked
directory = "NewSample.zip"
# Unpacking the archive dir
shutil.unpack_archive(directory, "extracted_dir")
print(f"Successfully extracted the files from {directory}.")
输出
Successfully extracted the files from NewSample.zip.
结论
shutil我们确实学会了使用该模块处理高级文件操作。我们已经学会了如何
-
将文件或目录复制到另一个目录
-
复制文件的元数据
-
将文件或目录永久移动到另一个位置
-
删除并复制目录树
除了这些操作,我们还看到了 Shutil 模块提供的一些很酷的方法。