Python 中复制文件的方法
技术背景
在 Python 编程中,经常会遇到需要复制文件的场景,例如数据备份、文件迁移等。Python 提供了多种方式来实现文件复制,这些方式各有特点,可以根据具体需求进行选择。
实现步骤
1. 使用 shutil
模块
shutil
模块提供了多个用于文件和目录操作的高级函数,以下是几种常用的文件复制方法:
shutil.copyfile(src, dst)
:将 src
文件的内容复制到 dst
文件。src
和 dst
都需要是包含路径的完整文件名,目标文件必须可写,若 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
os.system('cp source.txt destination.txt')
os.system('copy source.txt destination.txt')
|
3. 使用 subprocess
模块
subprocess
模块可以创建新的进程并与之交互,同样可以用于执行系统命令来复制文件。
1 2 3 4 5
| import subprocess
status = subprocess.call('cp source.txt destination.txt', shell=True)
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) 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
try: shutil.copyfile('source.txt', 'destination.txt') print("使用 shutil.copyfile 复制成功") except Exception as e: print(f"使用 shutil.copyfile 复制失败: {e}")
if os.name == 'posix': os.system('cp source.txt destination.txt') elif os.name == 'nt': os.system('copy source.txt destination.txt')
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)
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.copyfile
和 shutil.copyfileobj
。手动逐块复制的方式在处理大文件时性能也不错,但代码相对复杂。而使用 os.system
和 subprocess
执行系统命令的方式,由于涉及到创建新进程,性能相对较低,并且不具有跨平台性。