Python提供了丰富且灵活的文件操作API,本文将详细介绍文件读写、打开、关闭等核心方法,并配有完整的代码实例。
一、文件打开方法
1. open() 函数
open() 是Python中最基础、最常用的文件打开方法。
语法:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
常用参数说明:
| 参数 | 说明 |
|---|---|
file |
文件路径(字符串) |
mode |
打开模式(见下表) |
encoding |
编码格式(如 'utf-8') |
errors |
编码错误处理方式 |
newline |
控制换行符行为 |
常用打开模式:
| 模式 | 说明 |
|---|---|
'r' |
只读(默认) |
'w' |
只写,会覆盖已有文件 |
'a' |
追加模式,在文件末尾添加内容 |
'x' |
独占创建,文件已存在则报错 |
'b' |
二进制模式 |
't' |
文本模式(默认) |
'+' |
读写模式 |
组合模式示例:
'rb'--- 二进制只读'wb'--- 二进制只写'r+'--- 读写(文件必须存在)'w+'--- 读写(会覆盖文件)'a+'--- 读写追加
2. 使用 with 语句(推荐)
使用 with 语句可以自动管理文件关闭,即使发生异常也能确保文件被正确关闭。
实例1:基本打开与读取
# 使用 with 语句打开文件并读取
with open('example.txt', 'r', encoding='utf-8') as f:
content = f.read()
print(content)
# 离开 with 块后,文件自动关闭
实例2:指定编码打开
# 以 UTF-8 编码打开中文文件
with open('chinese.txt', 'r', encoding='utf-8') as file:
text = file.read()
print(text)
实例3:二进制模式打开
# 以二进制模式读取图片文件
with open('image.png', 'rb') as img_file:
image_data = img_file.read()
print(f"图片大小: {len(image_data)} 字节")
实例4:创建新文件(独占模式)
# 使用 'x' 模式创建新文件,如果文件已存在会报错
try:
with open('new_file.txt', 'x', encoding='utf-8') as f:
f.write('这是新创建的文件')
print("文件创建成功")
except FileExistsError:
print("文件已存在,无法创建")
二、文件读取方法
1. read() 方法
读取文件全部内容或指定字节数。
实例5:读取全部内容
with open('data.txt', 'r', encoding='utf-8') as f:
content = f.read()
print(content)
实例6:读取指定字节数
with open('data.txt', 'r', encoding='utf-8') as f:
# 读取前 100 个字符
first_100 = f.read(100)
print(first_100)
# 再读取接下来的 50 个字符
next_50 = f.read(50)
print(next_50)
2. readline() 方法
逐行读取文件内容。
实例7:逐行读取
with open('data.txt', 'r', encoding='utf-8') as f:
line1 = f.readline() # 读取第一行
line2 = f.readline() # 读取第二行
print(f"第一行: {line1.strip()}")
print(f"第二行: {line2.strip()}")
实例8:循环读取所有行
with open('data.txt', 'r', encoding='utf-8') as f:
line_number = 1
while True:
line = f.readline()
if not line:
break
print(f"第 {line_number} 行: {line.strip()}")
line_number += 1
3. readlines() 方法
读取所有行并返回列表。
实例9:读取为列表
with open('data.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
# lines 是一个列表,每个元素是一行内容
for i, line in enumerate(lines, 1):
print(f"{i}: {line.strip()}")
实例10:配合列表推导式
with open('data.txt', 'r', encoding='utf-8') as f:
# 读取所有行并去除末尾换行符
lines = [line.strip() for line in f.readlines()]
print(lines)
4. 直接迭代文件对象
文件对象本身是可迭代的,这是最高效的方式。
实例11:直接迭代
with open('data.txt', 'r', encoding='utf-8') as f:
for line in f:
print(line.strip())
实例12:带行号的迭代
with open('data.txt', 'r', encoding='utf-8') as f:
for line_number, line in enumerate(f, 1):
print(f"{line_number}: {line.strip()}")
三、文件写入方法
1. write() 方法
写入字符串到文件。
实例13:写入字符串
with open('output.txt', 'w', encoding='utf-8') as f:
f.write('Hello, World!\n')
f.write('这是第二行内容\n')
f.write('Python 文件操作很简单\n')
print("写入完成")
实例14:覆盖写入
# 'w' 模式会清空原有内容
with open('output.txt', 'w', encoding='utf-8') as f:
f.write('新的内容,旧内容已被覆盖\n')
2. writelines() 方法
写入字符串列表。
实例15:写入列表
lines = [
'第一行\n',
'第二行\n',
'第三行\n'
]
with open('output.txt', 'w', encoding='utf-8') as f:
f.writelines(lines)
print("列表写入完成")
实例16:动态生成内容并写入
# 生成 10 行数据并写入
data = [f"这是第 {i} 行数据\n" for i in range(1, 11)]
with open('numbers.txt', 'w', encoding='utf-8') as f:
f.writelines(data)
print("数据写入完成")
3. 追加写入
使用 'a' 模式在文件末尾添加内容。
实例17:追加内容
with open('log.txt', 'a', encoding='utf-8') as f:
f.write('2024-01-15 10:30:00 - 用户登录\n')
f.write('2024-01-15 10:31:00 - 操作完成\n')
print("日志追加完成")
实例18:追加并读取
with open('log.txt', 'a+', encoding='utf-8') as f:
# 先追加内容
f.write('新日志条目\n')
# 移动指针到开头读取
f.seek(0)
content = f.read()
print(content)
四、文件关闭方法
1. close() 方法
显式关闭文件。
实例19:手动关闭
f = open('data.txt', 'r', encoding='utf-8')
try:
content = f.read()
print(content)
finally:
f.close()
print("文件已关闭")
2. with 语句自动关闭(强烈推荐)
实例20:自动关闭
with open('data.txt', 'r', encoding='utf-8') as f:
content = f.read()
print(content)
# 这里文件已经自动关闭,无需手动调用 close()
实例21:多个文件同时操作
# 同时读取源文件和写入目标文件
with open('source.txt', 'r', encoding='utf-8') as src, \
open('destination.txt', 'w', encoding='utf-8') as dst:
for line in src:
dst.write(line.upper())
print("文件复制并转换完成")
五、文件指针操作
1. seek() 方法
移动文件指针位置。
实例22:seek() 基本用法
with open('data.txt', 'r+', encoding='utf-8') as f:
# 读取前 20 个字符
print(f"前20个字符: {f.read(20)}")
# 获取当前位置
current_pos = f.tell()
print(f"当前位置: {current_pos}")
# 移动到文件开头
f.seek(0)
print(f"回到开头后读取: {f.read(10)}")
实例23:seek() 偏移量
with open('data.txt', 'rb') as f:
# 从文件开头偏移 10 字节
f.seek(10, 0)
print(f"从开头偏移10字节: {f.read(20)}")
# 从当前位置偏移 5 字节
f.seek(5, 1)
print(f"从当前位置偏移5字节: {f.read(20)}")
# 从文件末尾偏移 -20 字节(需要二进制模式)
f.seek(-20, 2)
print(f"从末尾偏移-20字节: {f.read()}")
2. tell() 方法
获取当前文件指针位置。
实例24:tell() 用法
with open('data.txt', 'r', encoding='utf-8') as f:
print(f"初始位置: {f.tell()}")
f.read(50)
print(f"读取50字符后位置: {f.tell()}")
f.readline()
print(f"再读取一行后位置: {f.tell()}")
六、综合实例
实例25:文件复制程序
def copy_file(src_path, dst_path):
"""复制文件"""
with open(src_path, 'rb') as src, open(dst_path, 'wb') as dst:
while True:
chunk = src.read(4096) # 每次读取 4KB
if not chunk:
break
dst.write(chunk)
print(f"文件已从 {src_path} 复制到 {dst_path}")
# 使用
copy_file('source.txt', 'backup.txt')
实例26:CSV 文件读写
import csv
# 写入 CSV
with open('data.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['姓名', '年龄', '城市'])
writer.writerow(['张三', 25, '北京'])
writer.writerow(['李四', 30, '上海'])
# 读取 CSV
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
实例27:JSON 文件读写
import json
data = {
'name': '张三',
'age': 25,
'skills': ['Python', 'JavaScript', 'SQL']
}
# 写入 JSON
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# 读取 JSON
with open('data.json', 'r', encoding='utf-8') as f:
loaded_data = json.load(f)
print(loaded_data)
实例28:大文件处理(逐行处理)
def process_large_file(file_path):
"""逐行处理大文件,内存友好"""
line_count = 0
word_count = 0
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
line_count += 1
word_count += len(line.split())
print(f"总行数: {line_count}")
print(f"总词数: {word_count}")
process_large_file('large_file.txt')
实例29:日志文件追加与读取
from datetime import datetime
def write_log(message):
"""写入日志"""
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
with open('app.log', 'a', encoding='utf-8') as f:
f.write(f"[{timestamp}] {message}\n")
def read_logs():
"""读取所有日志"""
with open('app.log', 'r', encoding='utf-8') as f:
return f.readlines()
# 使用
write_log("应用程序启动")
write_log("用户登录成功")
write_log("数据保存完成")
logs = read_logs()
for log in logs:
print(log.strip())
实例30:临时文件操作
import tempfile
# 创建临时文件
with tempfile.NamedTemporaryFile(mode='w+', delete=False, suffix='.txt') as tmp:
tmp.write('这是临时文件的内容\n')
tmp.write('临时文件在程序结束后自动删除\n')
print(f"临时文件路径: {tmp.name}")
# 回到文件开头读取
tmp.seek(0)
print(tmp.read())
# 临时文件在 with 块结束后仍然存在(因为 delete=False)
# 可以手动删除
import os
os.unlink(tmp.name)
七、常见错误与处理
实例31:异常处理
try:
with open('nonexistent.txt', 'r', encoding='utf-8') as f:
content = f.read()
except FileNotFoundError:
print("文件不存在!")
except PermissionError:
print("权限不足,无法访问文件!")
except UnicodeDecodeError:
print("文件编码错误,请尝试其他编码!")
except Exception as e:
print(f"发生错误: {e}")
实例32:检查文件是否存在
import os
file_path = 'data.txt'
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
print(f.read())
else:
print(f"文件 {file_path} 不存在")
八、最佳实践总结
- 始终使用
with语句:自动管理文件关闭,代码更安全 - 指定编码 :明确指定
encoding='utf-8',避免编码问题 - 使用
'rb'/'wb'处理二进制文件:图片、视频等非文本文件 - 大文件使用逐行读取:避免一次性加载到内存
- 使用
newline=''处理 CSV:避免额外的空行 - 处理异常:使用 try-except 捕获可能的文件操作错误
本文档涵盖了 Python 文件操作的核心方法,从基础的打开、读取、写入到高级的指针操作和综合应用,配合丰富的实例代码,帮助您全面掌握 Python 文件操作技术。