Python 中复制文件的方法

Python 中复制文件的方法

技术背景

在 Python 编程中,经常会遇到需要复制文件的场景,例如数据备份、文件迁移等。Python 提供了多种方式来实现文件复制,这些方式各有特点,可以根据具体需求进行选择。

实现步骤

1. 使用 shutil 模块

shutil 模块提供了多个用于文件和目录操作的高级函数,以下是几种常用的文件复制方法:

  • shutil.copyfile(src, dst):将 src 文件的内容复制到 dst 文件。srcdst 都需要是包含路径的完整文件名,目标文件必须可写,若 dst 已存在则会被替换。
1
2
import shutil
shutil.copyfile('source.txt', 'destination.txt')
  • shutil.copy(src, dst)dst 可以是一个文件夹,若 dst 是文件夹,则会使用 src 的基本文件名在该文件夹中创建新文件。
1
2
import shutil
shutil.copy('source.txt', 'destination_folder')
  • shutil.copy2(src, dst):与 shutil.copy 类似,但会保留更多的文件元数据(如时间戳)。
1
2
import shutil
shutil.copy2('source.txt', 'destination_folder')
  • shutil.copyfileobj(src_file_object, dest_file_object[, length]):用于复制文件对象,需要先打开文件对象。
1
2
3
4
5
6
7
8
import shutil
file_src = 'source.txt'
f_src = open(file_src, 'rb')
file_dest = 'destination.txt'
f_dest = open(file_dest, 'wb')
shutil.copyfileobj(f_src, f_dest)
f_src.close()
f_dest.close()

2. 使用 os 模块

os 模块提供了与操作系统进行交互的功能,可以通过执行系统命令来复制文件,但这种方法不具有跨平台性。

1
2
3
4
5
import os
# 在 Unix/Linux 系统中
os.system('cp source.txt destination.txt')
# 在 Windows 系统中
os.system('copy source.txt destination.txt')

3. 使用 subprocess 模块

subprocess 模块可以创建新的进程并与之交互,同样可以用于执行系统命令来复制文件。

1
2
3
4
5
import subprocess
# 在 Linux/Unix 系统中
status = subprocess.call('cp source.txt destination.txt', shell=True)
# 在 Windows 系统中
status = subprocess.call('copy source.txt destination.txt', shell=True)

4. 使用 pathlib 模块(Python 3.5+)

pathlib 模块提供了面向对象的文件系统路径操作方式,适用于小文件的复制。

1
2
3
4
from pathlib import Path
source = Path('source.txt')
destination = Path('destination.txt')
destination.write_bytes(source.read_bytes())

5. 手动实现文件复制

可以手动打开源文件和目标文件,逐块读取并写入数据。

1
2
3
4
5
6
with open('sourcefile', 'rb') as f, open('destfile', 'wb') as g:
while True:
block = f.read(16*1024*1024) # 以 16 MB 为块进行复制
if not block: # 到达文件末尾
break
g.write(block)

核心代码

以下是一个综合示例,展示了如何根据不同需求选择合适的文件复制方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import shutil
import os
import subprocess
from pathlib import Path

# 使用 shutil.copyfile
try:
shutil.copyfile('source.txt', 'destination.txt')
print("使用 shutil.copyfile 复制成功")
except Exception as e:
print(f"使用 shutil.copyfile 复制失败: {e}")

# 使用 os.system
if os.name == 'posix': # Unix/Linux 系统
os.system('cp source.txt destination.txt')
elif os.name == 'nt': # Windows 系统
os.system('copy source.txt destination.txt')

# 使用 subprocess.call
if os.name == 'posix':
status = subprocess.call('cp source.txt destination.txt', shell=True)
elif os.name == 'nt':
status = subprocess.call('copy source.txt destination.txt', shell=True)

# 使用 pathlib
source = Path('source.txt')
destination = Path('destination.txt')
try:
destination.write_bytes(source.read_bytes())
print("使用 pathlib 复制成功")
except Exception as e:
print(f"使用 pathlib 复制失败: {e}")

# 手动复制
with open('sourcefile', 'rb') as f, open('destfile', 'wb') as g:
while True:
block = f.read(16*1024*1024)
if not block:
break
g.write(block)

最佳实践

  • 优先使用 shutil 模块shutil 模块提供了高级的文件和目录操作功能,具有良好的跨平台性和安全性,并且可以处理大多数文件复制场景。
  • 处理异常情况:在进行文件复制时,可能会遇到各种异常,如文件不存在、目标目录不可写等。因此,建议使用 try-except 语句来捕获并处理这些异常。
  • 考虑文件大小:对于大文件,建议使用 shutil.copyfileobj 或手动逐块复制的方式,避免一次性将整个文件加载到内存中。

常见问题

1. 目标目录不存在怎么办?

在使用 shutil 模块复制文件时,如果目标目录不存在,会抛出 FileNotFoundError 异常。可以使用 os.makedirs 函数先创建目标目录。

1
2
3
4
5
6
7
import os
import shutil

destination_path = 'path/to/destination_folder'
source_path = 'source.txt'
os.makedirs(os.path.dirname(destination_path), exist_ok=True)
shutil.copyfile(source_path, destination_path)

2. 如何保留文件元数据?

可以使用 shutil.copy2 函数来保留文件的元数据,如修改时间、访问时间等。

1
2
import shutil
shutil.copy2('source.txt', 'destination.txt')

3. 不同方法的性能差异如何?

一般来说,shutil 模块的性能较好,尤其是 shutil.copyfileshutil.copyfileobj。手动逐块复制的方式在处理大文件时性能也不错,但代码相对复杂。而使用 os.systemsubprocess 执行系统命令的方式,由于涉及到创建新进程,性能相对较低,并且不具有跨平台性。


Python 中复制文件的方法
https://119291.xyz/posts/2025-04-21.python-file-copying-methods/
作者
ww
发布于
2025年4月21日
许可协议