文本文件读写:read()、readline()、readlines()、write()、writelines()
文件读写,说白了就是让程序和硬盘上的文件「对话」。我刚开始学 Python 时,觉得这玩意儿特简单——不就是打开、读写、关闭嘛。直到有一次我写了个日志分析脚本,跑了一整夜,第二天发现文件没关,数据全丢了……嗯,从那以后我再也不敢小看文件操作了。
今天咱们就聊聊文本文件的读写。Python 内置的 open() 函数是核心,配合 read()、readline()、readlines()、write()、writelines() 这几个方法,基本能搞定 90% 的场景。
核心要点:文本文件操作遵循「打开 → 读写 → 关闭」三步走。忘记关闭文件?用 with 语句自动搞定。
1. 打开文件:open() 的基本用法
先看个最简单的例子:
# 打开文件,读取全部内容
f = open('example.txt', 'r', encoding='utf-8')
content = f.read()
f.close()
这里 'r' 表示只读模式。我习惯把 encoding='utf-8' 写上,因为 Windows 默认编码是 gbk,不指定的话容易乱码。你想想看,要是辛辛苦苦写的数据读出来全是乱码,多闹心。
更推荐的做法是用 with 语句:
with open('example.txt', 'r', encoding='utf-8') as f:
content = f.read()
# 离开 with 块后,文件自动关闭
这样就不用记着 f.close() 了。我在项目中几乎只用 with 写法,省心。
2. read():一口气读完
read() 会把整个文件内容当作一个字符串返回。适合小文件:
with open('poem.txt', 'r', encoding='utf-8') as f:
data = f.read()
print(data)
print(f'共 {len(data)} 个字符')
也可以指定读取的字符数:
with open('poem.txt', 'r', encoding='utf-8') as f:
chunk = f.read(100) # 只读前 100 个字符
print(chunk)
注意:千万别用 read() 读大文件!比如几个 GB 的日志文件,一口气读到内存里,程序直接崩掉。我曾经在服务器上犯过这个错,结果 OOM(内存溢出)了,被运维大哥骂了一顿。
3. readline():逐行读取
readline() 每次只读一行,适合处理大文件:
with open('big_log.txt', 'r', encoding='utf-8') as f:
line = f.readline()
while line:
print(line.strip()) # strip() 去掉换行符
line = f.readline()
更 Pythonic 的写法是直接遍历文件对象:
with open('big_log.txt', 'r', encoding='utf-8') as f:
for line in f:
print(line.strip())
这两种方式本质一样,都是逐行读取,不会一次性加载整个文件。我处理几百 MB 的日志时,就用这个套路。
4. readlines():读取所有行
readlines() 返回一个列表,每个元素是一行字符串:
with open('names.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
print(f'共有 {len(lines)} 行')
for line in lines:
print(line.strip())
小技巧:readlines() 适合文件不大、需要随机访问各行的情况。如果只是顺序处理,用 for line in f 更省内存。
5. write():写入字符串
write() 把字符串写入文件。注意模式要改成 'w'(覆盖写)或 'a'(追加写):
with open('output.txt', 'w', encoding='utf-8') as f:
f.write('Hello, World!\n')
f.write('这是第二行\n')
f.write('这是第三行\n')
如果文件已存在,'w' 模式会清空它。想保留原有内容?用 'a' 模式:
with open('output.txt', 'a', encoding='utf-8') as f:
f.write('这行会追加到文件末尾\n')
注意:write() 不会自动加换行符。你需要手动加 \n。我刚开始写时经常忘记,结果所有内容挤在一行,丑得没法看。
6. writelines():写入多行
writelines() 接受一个可迭代对象(比如列表),把每个元素写入文件:
lines = ['第一行\n', '第二行\n', '第三行\n']
with open('output.txt', 'w', encoding='utf-8') as f:
f.writelines(lines)
注意:writelines() 也不会自动加换行符。列表里的每个字符串必须自己带 \n。我习惯用列表推导式来加:
data = ['苹果', '香蕉', '橘子']
lines = [item + '\n' for item in data]
with open('fruits.txt', 'w', encoding='utf-8') as f:
f.writelines(lines)
7. 知识体系总览
下面这张图帮你理清文本文件读写的核心逻辑:
8. 实战对比:不同读取方式的性能
我拿一个 100MB 的日志文件做了个测试,结果如下:
| 方法 | 内存占用 | 速度 | 适用场景 |
|---|---|---|---|
| read() | 高(整个文件) | 快 | 小文件(< 100MB) |
| readline() | 低(一行) | 中等 | 大文件逐行处理 |
| readlines() | 高(所有行列表) | 快 | 中等文件,需要随机访问 |
| for line in f | 低(一行) | 快 | 大文件,推荐做法 |
我的建议:处理大文件时,优先用 for line in f。它既省内存,又简洁。小文件用 read() 或 readlines() 都行,看个人习惯。
9. 避坑指南
- 编码问题:读写时编码不一致会报错。我统一用
encoding='utf-8',省心。 - 换行符:Windows 用
\r\n,Linux 用\n。Python 的open()默认做了转换,但写入时最好手动加\n。 - 文件不存在:读模式打开不存在的文件会报
FileNotFoundError。写模式会自动创建文件。 - 忘记关闭:不用
with的话,记得f.close()。否则文件句柄泄漏,程序跑久了会出问题。
好了,文本文件读写就聊到这儿。这些方法看着简单,但用好了能解决很多实际问题。下次咱们聊聊二进制文件的读写,那个更刺激。
可可精品资料库