

💾 说明 :几乎所有程序都需要与文件打交道------保存配置、记录日志、处理用户数据。本篇系统讲解 Python 文件操作的核心方法 ,涵盖文本/二进制读写、路径处理、异常安全、编码问题及常用数据格式(CSV、JSON),助你写出可靠、跨平台、无乱码的文件处理代码。
你将掌握:
open()的正确用法与编码陷阱- 为什么必须用
with语句? - 读写 CSV 和 JSON 文件
- 处理大文件的高效策略
- 路径拼接的最佳实践(
pathlib)
1. 基础文件读写:open() 与 with
✅ 推荐写法:使用上下文管理器
python
# 写入文件
with open("hello.txt", "w", encoding="utf-8") as f:
f.write("你好,世界!")
# 读取文件
with open("hello.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content) # 你好,世界!
🔑 关键点:
- 必须指定
encoding="utf-8"(避免 Windows 默认gbk导致乱码)- 永远用
with:自动关闭文件,即使出错也安全
2. 文件打开模式速查表
| 模式 | 含义 | 说明 |
|---|---|---|
'r' |
只读(默认) | 文件必须存在 |
'w' |
写入 | 覆盖原文件,不存在则创建 |
'a' |
追加 | 在文件末尾添加,不覆盖 |
'x' |
独占创建 | 文件存在则失败(防覆盖) |
'b' |
二进制模式 | 如 'rb', 'wb' |
'+' |
读写 | 如 'r+'(可读可写,不创建) |
示例:追加日志
python
with open("app.log", "a", encoding="utf-8") as f:
f.write("[INFO] 程序启动\n")
3. 读取文件的不同方式
| 方法 | 适用场景 |
|---|---|
f.read() |
一次性读取全部内容(小文件) |
f.readline() |
逐行读取(节省内存) |
f.readlines() |
读取所有行到列表(需随机访问行) |
for line in f |
推荐! 高效逐行迭代(大文件) |
处理大文件(推荐方式)
python
# 安全处理 GB 级日志文件
with open("huge.log", "r", encoding="utf-8") as f:
for line in f: # 一次只加载一行到内存
if "ERROR" in line:
print(line.strip())
✅ 优势:内存占用恒定,不随文件大小增长。
4. 路径处理:告别字符串拼接!
❌ 错误做法(不可移植)
python
# Windows 用 \,Linux/Mac 用 /,极易出错!
filepath = "data" + "\\" + "input.txt"
✅ 正确做法:使用 pathlib(Python 3.4+)
python
from pathlib import Path
data_dir = Path("data")
file_path = data_dir / "input.txt" # 自动适配操作系统
# 检查并创建目录
data_dir.mkdir(exist_ok=True)
# 读取文件
content = file_path.read_text(encoding="utf-8")
💡
pathlib是现代 Python 文件路径操作的标准方式。
5. 数据持久化:JSON 与 CSV
5.1 JSON:结构化数据交换
python
import json
from pathlib import Path
# 写入
data = {"users": ["Alice", "Bob"], "version": 1.0}
Path("config.json").write_text(
json.dumps(data, ensure_ascii=False, indent=2),
encoding="utf-8"
)
# 读取
loaded = json.loads(Path("config.json").read_text(encoding="utf-8"))
print(loaded["users"]) # ['Alice', 'Bob']
⚠️ 注意:
json只支持基本类型(dict,list,str,int,float,bool,None)
5.2 CSV:表格数据处理
python
import csv
from pathlib import Path
# 写入 CSV
with open("students.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["姓名", "年龄", "班级"])
writer.writerow(["小明", 18, "高三(1)班"])
# 读取 CSV(推荐 DictReader)
with open("students.csv", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['姓名']} - {row['班级']}")
# 小明 - 高三(1)班
🔑 关键参数:
newline="":防止 Windows 多余空行DictReader:按列名访问,比索引更清晰
6. 二进制文件操作:图片、音频等
python
# 复制图片
with open("photo.jpg", "rb") as src:
with open("photo_copy.jpg", "wb") as dst:
dst.write(src.read())
# 或用 shutil(更高效)
import shutil
shutil.copy2("photo.jpg", "backup/photo_copy.jpg")
✅ 二进制模式(
'rb','wb')不需要指定 encoding
7. 异常处理:让文件操作更健壮
python
from pathlib import Path
def safe_read_file(filepath):
path = Path(filepath)
try:
if not path.exists():
raise FileNotFoundError(f"文件不存在: {filepath}")
return path.read_text(encoding="utf-8")
except PermissionError:
print("❌ 权限不足,无法读取文件")
except UnicodeDecodeError:
print("❌ 文件编码不是 UTF-8,请检查")
except Exception as e:
print(f"❌ 未知错误: {e}")
return None
content = safe_read_file("secret.txt")
🛡️ 常见异常:
FileNotFoundErrorPermissionErrorIsADirectoryErrorUnicodeDecodeError(编码错误)
8. 实用技巧与最佳实践
| 场景 | 推荐方案 |
|---|---|
| 临时文件 | tempfile.NamedTemporaryFile() |
| 文件备份 | shutil.copy2(src, dst)(保留元数据) |
| 递归遍历目录 | Path.rglob("*.txt") |
| 获取文件大小 | Path("file.txt").stat().st_size |
| 安全写入(防中断损坏) | 先写临时文件,再重命名 |
安全写入示例(原子操作)
python
from pathlib import Path
import os
def atomic_write(filepath, content):
"""安全写入:避免程序崩溃导致文件损坏"""
temp_path = Path(filepath).with_suffix(".tmp")
try:
temp_path.write_text(content, encoding="utf-8")
os.replace(temp_path, filepath) # 原子替换
except Exception:
temp_path.unlink(missing_ok=True) # 清理临时文件
raise
9. 总结:文件操作黄金法则
- 永远用
with open(...) - 显式指定
encoding="utf-8"(文本文件) - 用
pathlib.Path处理路径 - 大文件用
for line in file逐行读取 - 结构化数据优先选 JSON/CSV
- 捕获并处理常见文件异常
💾 记住 :
"文件是程序与外部世界的桥梁,
安全、可靠、跨平台是你的责任。"
下一步练习
- 改造你的 To-Do List 项目 :
- 用 JSON 保存任务列表
- 实现"自动备份"功能(每天生成
todo_backup_20251212.json)
- 编写一个日志分析脚本 :
- 读取
app.log - 统计 ERROR 行数并输出到
error_report.txt
- 读取
- 尝试用 CSV 存储联系人,支持增删查改
🐍 掌控文件,就是掌控数据。
你已具备构建完整本地应用的能力!
继续编码,让数据为你所用!

