Python 文件读写
目录
学习目标
- 掌握文件的打开、读取和写入操作
- 理解不同的文件模式
- 学会处理文本文件和二进制文件
- 掌握文件编码和常见文件格式处理
1. 打开文件
1.1 open() 函数
# 基本语法
# open(file, mode='r', encoding=None, ...)
# 读取文本文件
f = open('data.txt', 'r', encoding='utf-8')
content = f.read()
f.close()
# 推荐:使用 with 语句(自动关闭)
with open('data.txt', 'r', encoding='utf-8') as f:
content = f.read()
# 文件已自动关闭1.2 文件模式
| 模式 | 说明 |
|---|---|
'r' |
读取(默认) |
'w' |
写入,会覆盖原有内容 |
'x' |
独占创建,文件已存在则报错 |
'a' |
追加写入 |
'b' |
二进制模式 |
't' |
文本模式(默认) |
'+' |
读写模式 |
# 常用模式组合
'r' # 只读文本
'w' # 只写文本(覆盖)
'a' # 追加文本
'rb' # 只读二进制
'wb' # 只写二进制
'r+' # 读写(文件必须存在)
'w+' # 读写(覆盖或创建)2. 读取文件
2.1 读取整个文件
with open('example.txt', 'r', encoding='utf-8') as f:
content = f.read() # 读取全部内容
print(content)2.2 逐行读取
# 方法1:readlines()
with open('example.txt', 'r', encoding='utf-8') as f:
lines = f.readlines() # 返回列表
for line in lines:
print(line.strip())
# 方法2:直接迭代(推荐,内存友好)
with open('example.txt', 'r', encoding='utf-8') as f:
for line in f:
print(line.strip())
# 方法3:readline() 逐行
with open('example.txt', 'r', encoding='utf-8') as f:
while True:
line = f.readline()
if not line:
break
print(line.strip())2.3 指定读取大小
with open('example.txt', 'r', encoding='utf-8') as f:
# 读取前100个字符
chunk = f.read(100)
print(f"前100个字符: {chunk}")
# 继续读取
chunk2 = f.read(100)
print(f"接下来100个字符: {chunk2}")3. 写入文件
3.1 写入文本
# 覆盖写入
with open('output.txt', 'w', encoding='utf-8') as f:
f.write('第一行\n')
f.write('第二行\n')
# 追加写入
with open('output.txt', 'a', encoding='utf-8') as f:
f.write('第三行(追加)\n')
# 写入多行
lines = ['行1\n', '行2\n', '行3\n']
with open('output.txt', 'w', encoding='utf-8') as f:
f.writelines(lines)3.2 print 重定向到文件
with open('log.txt', 'w', encoding='utf-8') as f:
print('日志信息1', file=f)
print('日志信息2', file=f)
print('带变量:', 42, file=f)4. 二进制文件操作
4.1 读写二进制
# 写入二进制数据
data = bytes([0, 1, 2, 255])
with open('binary.bin', 'wb') as f:
f.write(data)
# 读取二进制数据
with open('binary.bin', 'rb') as f:
data = f.read()
print(data) # b'\x00\x01\x02\xff'
print(list(data)) # [0, 1, 2, 255]4.2 复制文件
def copy_file(src, dst):
"""复制文件"""
with open(src, 'rb') as f_src:
with open(dst, 'wb') as f_dst:
while True:
chunk = f_src.read(4096) # 分块读取
if not chunk:
break
f_dst.write(chunk)
# 使用
copy_file('source.jpg', 'backup.jpg')5. 文件指针操作
with open('data.txt', 'r+', encoding='utf-8') as f:
# 读取前10个字符
print(f.read(10))
# 获取当前位置
print(f"当前位置: {f.tell()}")
# 移动到文件开头
f.seek(0)
print(f"回到开头后: {f.read(5)}")
# seek(offset, whence)
# whence: 0=开头(默认), 1=当前位置, 2=文件末尾
f.seek(0, 2) # 移动到末尾
print(f"文件大小: {f.tell()}")6. 编码处理
6.1 指定编码
# UTF-8(推荐)
with open('utf8.txt', 'w', encoding='utf-8') as f:
f.write('中文内容')
# GBK
with open('gbk.txt', 'w', encoding='gbk') as f:
f.write('中文内容')
# 读取时指定编码
with open('gbk.txt', 'r', encoding='gbk') as f:
print(f.read())6.2 自动检测编码
# 使用 chardet 库检测编码(需安装: pip install chardet)
# import chardet
#
# with open('unknown.txt', 'rb') as f:
# result = chardet.detect(f.read())
# print(result) # {'encoding': 'UTF-8', 'confidence': 0.99}6.3 处理编码错误
# 忽略错误字符
with open('file.txt', 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
# 用替换字符
with open('file.txt', 'r', encoding='utf-8', errors='replace') as f:
content = f.read()
# 严格模式(默认,遇到错误抛出异常)
with open('file.txt', 'r', encoding='utf-8', errors='strict') as f:
content = f.read()7. 常见文件格式处理
7.1 CSV 文件
import csv
# 写入 CSV
with open('data.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['姓名', '年龄', '城市'])
writer.writerow(['Alice', 25, '北京'])
writer.writerow(['Bob', 30, '上海'])
# 读取 CSV
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
print(row)
# 使用 DictReader
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['姓名']}: {row['年龄']}岁")7.2 JSON 文件
import json
data = {
"name": "Alice",
"age": 25,
"hobbies": ["读书", "游泳"]
}
# 写入 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 = json.load(f)
print(loaded)
# JSON 字符串
json_str = json.dumps(data, ensure_ascii=False)
print(json_str)
parsed = json.loads(json_str)
print(parsed)7.3 临时文件
import tempfile
# 创建临时文件
with tempfile.TemporaryFile(mode='w+', encoding='utf-8') as f:
f.write('临时数据')
f.seek(0)
print(f.read())
# 文件自动删除
# 创建有名临时文件
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as f:
f.write('有名临时文件')
print(f"临时文件路径: {f.name}")
# 需要手动删除
# 临时目录
with tempfile.TemporaryDirectory() as tmpdir:
print(f"临时目录: {tmpdir}")
# 在目录中创建文件...
# 目录自动删除8. 文件和目录操作
import os
import shutil
# 文件操作
os.rename('old.txt', 'new.txt') # 重命名
os.remove('file.txt') # 删除文件
shutil.copy('src.txt', 'dst.txt') # 复制文件
shutil.move('src.txt', 'dst/') # 移动文件
# 检查文件
print(os.path.exists('file.txt')) # 是否存在
print(os.path.isfile('file.txt')) # 是否是文件
print(os.path.getsize('file.txt')) # 文件大小
# 路径操作
print(os.path.join('folder', 'file.txt')) # folder/file.txt
print(os.path.abspath('file.txt')) # 绝对路径
print(os.path.dirname('/a/b/c.txt')) # /a/b
print(os.path.basename('/a/b/c.txt')) # c.txt
print(os.path.splitext('file.txt')) # ('file', '.txt')本节小结
- 打开文件:使用
with语句自动管理资源 - 文件模式:
r/w/a/x配合b/t/+满足各种需求 - 读取方式:
read()、readline()、迭代文件对象 - 编码处理:始终显式指定
encoding='utf-8' - 常见格式:
csv、json使用标准库处理 - 临时文件:
tempfile模块安全创建临时资源
练习
- 编写一个函数,统计文本文件的行数、单词数和字符数
- 实现一个配置文件解析器,支持 JSON 和 CSV 格式
- 编写程序合并多个文本文件,并去除重复行
- 创建一个日志文件处理器,自动按日期分割日志文件