
Python 提供了内置的 open() 函数和文件对象方法,用于文件的创建、读取、写入、追加等操作。核心是使用 with 语句自动管理文件资源。
一、文件打开模式
| 'r' | 只读(默认) | 文件必须存在,否则报错 |
| 'w' | 只写 | 创建新文件或覆盖已有文件 |
| 'a' | 追加 | 在文件末尾追加内容 |
| 'x' | 独占创建 | 文件存在时报错 |
| 'b' | 二进制模式 | 与其他模式组合,如 'rb'、'wb' |
| 't' | 文本模式(默认) | 与其他模式组合,如 'rt'、'wt' |
| '+' | 读写模式 | 与其他模式组合,如 'r+'、'w+' |
# 常用组合
f = open('file.txt', 'r') # 只读文本
f = open('file.txt', 'w') # 写入文本(覆盖)
f = open('file.txt', 'a') # 追加文本
f = open('file.bin', 'rb') # 读取二进制
f = open('file.bin', 'wb') # 写入二进制
f = open('file.txt', 'r+') # 读写文本
二、基本文件操作
1. 打开与关闭文件
# 方式1:手动关闭(不推荐)
f = open('test.txt', 'r')
content = f.read()
f.close() # 容易忘记
# 方式2:使用 with(推荐)
with open('test.txt', 'r') as f:
content = f.read()
# 自动关闭文件,即使发生异常
2. 读取文件
# 读取整个文件
with open('test.txt', 'r', encoding='utf-8') as f:
content = f.read()
print(content)
# 读取指定字节数
with open('test.txt', 'r') as f:
chunk = f.read(1024) # 读取前 1024 个字符
# 按行读取
with open('test.txt', 'r') as f:
line = f.readline() # 读取一行
lines = f.readlines() # 读取所有行到列表
# 逐行遍历(推荐大文件)
with open('test.txt', 'r') as f:
for line in f:
print(line.strip())
3. 写入文件
# 覆盖写入
with open('test.txt', 'w', encoding='utf-8') as f:
f.write('Hello, World!\\n')
f.write('第二行内容\\n')
# 写入多行
lines = ['第一行\\n', '第二行\\n', '第三行\\n']
with open('test.txt', 'w') as f:
f.writelines(lines)
# 追加写入
with open('test.txt', 'a') as f:
f.write('追加的内容\\n')
三、文件指针操作
with open('test.txt', 'r') as f:
# 获取当前位置
print(f.tell()) # 0
# 移动指针
f.seek(5) # 从文件开头偏移 5 字节
f.seek(0, 0) # 移动到开头
f.seek(0, 1) # 当前位置不变
f.seek(0, 2) # 移动到末尾
# 读取内容
content = f.read()
seek 参数说明
| f.seek(offset, 0) | 从文件开头偏移 |
| f.seek(offset, 1) | 从当前位置偏移 |
| f.seek(offset, 2) | 从文件末尾偏移 |
四、二进制文件操作
# 写入二进制数据
with open('image.jpg', 'rb') as src:
data = src.read()
with open('copy.jpg', 'wb') as dst:
dst.write(data)
# 高效复制(分块读取)
def copy_file(src_path, dst_path, chunk_size=8192):
with open(src_path, 'rb') as src:
with open(dst_path, 'wb') as dst:
while True:
chunk = src.read(chunk_size)
if not chunk:
break
dst.write(chunk)
# 处理其他二进制数据
import struct
with open('data.bin', 'wb') as f:
f.write(b'\\x00\\x01\\x02\\x03')
f.write(struct.pack('i', 12345)) # 写入整数
五、文件路径操作(os.path 和 pathlib)
1. 使用 os.path
import os
# 路径拼接
path = os.path.join('folder', 'subfolder', 'file.txt')
# 获取目录、文件名、扩展名
dirname = os.path.dirname(path) # 'folder/subfolder'
basename = os.path.basename(path) # 'file.txt'
name, ext = os.path.splitext(basename) # 'file', '.txt'
# 检查路径是否存在
exists = os.path.exists(path)
is_file = os.path.isfile(path)
is_dir = os.path.isdir(path)
# 获取文件大小
size = os.path.getsize(path)
# 列出目录内容
files = os.listdir('.')
2. 使用 pathlib(推荐)
from pathlib import Path
# 创建路径对象
path = Path('folder/subfolder/file.txt')
# 路径拼接
path = Path('folder') / 'subfolder' / 'file.txt'
# 获取信息
dirname = path.parent
filename = path.name
stem = path.stem # 文件名(无扩展名)
suffix = path.suffix # 扩展名
# 操作
path.exists()
path.is_file()
path.is_dir()
path.stat().st_size
# 遍历目录
for file in Path('.').iterdir():
if file.is_file():
print(file.name)
# 递归遍历所有 .py 文件
for file in Path('.').rglob('*.py'):
print(file)
六、常见编码处理
# 指定编码(避免乱码)
with open('test.txt', 'r', encoding='utf-8') as f:
content = f.read()
# 处理编码错误
with open('test.txt', 'r', encoding='utf-8', errors='ignore') as f:
content = f.read() # 忽略无法解码的字符
# errors 参数可选值
# 'ignore' – 忽略错误字符
# 'replace' – 用 ? 替换
# 'strict' – 抛出异常(默认)
七、常用文件操作
1. 文件的增删改查
import os
from pathlib import Path
# 创建文件
with open('new_file.txt', 'w') as f:
f.write('content')
# 重命名
os.rename('old.txt', 'new.txt')
Path('old.txt').rename('new.txt')
# 删除文件
os.remove('file.txt')
Path('file.txt').unlink()
# 创建目录
os.mkdir('new_folder')
Path('new_folder').mkdir(exist_ok=True)
# 删除目录
os.rmdir('empty_folder')
import shutil
shutil.rmtree('non_empty_folder')
# 复制文件
import shutil
shutil.copy('src.txt', 'dst.txt')
shutil.copy2('src.txt', 'dst.txt') # 保留元数据
2. 临时文件
from tempfile import TemporaryFile, NamedTemporaryFile, TemporaryDirectory
# 匿名临时文件(关闭后自动删除)
with TemporaryFile(mode='w+') as f:
f.write('temporary data')
f.seek(0)
print(f.read())
# 有名字的临时文件
with NamedTemporaryFile(mode='w+', delete=True) as f:
print(f.name) # 临时文件路径
f.write('data')
# 临时目录
with TemporaryDirectory() as temp_dir:
print(f'临时目录: {temp_dir}')
# 在目录中操作文件
八、大文件处理
# 1. 逐行处理(内存友好)
def process_large_file(file_path):
with open(file_path, 'r') as f:
for line in f:
# 处理每一行
process_line(line)
# 2. 分块读取
def process_by_chunks(file_path, chunk_size=8192):
with open(file_path, 'rb') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
process_chunk(chunk)
# 3. 使用 yield 实现流式处理
def read_lines(file_path):
with open(file_path, 'r') as f:
for line in f:
yield line.strip()
for line in read_lines('large.log'):
print(line)
九、CSV 文件操作
import csv
# 读取 CSV
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
# 读取字典格式
with open('data.csv', 'r') as f:
reader = csv.DictReader(f)
for row in reader:
print(row['name'], row['age'])
# 写入 CSV
with open('output.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['name', 'age', 'city'])
writer.writerow(['Alice', 25, 'Beijing'])
writer.writerows([
['Bob', 30, 'Shanghai'],
['Charlie', 35, 'Guangzhou']
])
十、JSON 文件操作
import json
data = {
'name': 'Alice',
'age': 25,
'city': 'Beijing',
'hobbies': ['reading', 'swimming']
}
# 写入 JSON
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2, ensure_ascii=False)
# 读取 JSON
with open('data.json', 'r', encoding='utf-8') as f:
loaded = json.load(f)
print(loaded['name'])
# 字符串转换
json_str = json.dumps(data, ensure_ascii=False)
obj = json.loads(json_str)
总表
| 打开文件 | open(file, mode) | 返回文件对象 |
| 读取全部 | f.read() | 读取整个文件 |
| 按行读取 | f.readline() | 读取一行 |
| 读取所有行 | f.readlines() | 返回行列表 |
| 遍历文件 | for line in f | 逐行迭代(推荐) |
| 写入 | f.write(str) | 写入字符串 |
| 写入多行 | f.writelines(list) | 写入字符串列表 |
| 关闭 | f.close() | 关闭文件(with 自动) |
| 移动指针 | f.seek(offset) | 移动文件指针 |
| 获取位置 | f.tell() | 获取当前位置 |
核心要点:
使用 with open() 自动管理文件资源
指定正确的编码 encoding='utf-8' 避免乱码
大文件使用逐行读取或分块读取节省内存
pathlib 是更现代的路径处理方式
区分文本模式和二进制模式('rb'、'wb')


