一、文件操作基础:打开文件、读取文件、写入文件、关闭文件
文件读写,说白了就是让程序和磁盘上的文件打交道。我刚开始学Python时,觉得这玩意儿特简单——不就是open、read、write、close嘛。但后来在项目中踩过几次坑,才发现这里面的门道还真不少。
今天咱们就把文件操作的基础彻底捋一遍。你想想看,不管是写日志、读配置、存数据,还是做爬虫、搞数据分析,哪个能绕开文件操作?所以这块基础打牢了,后面学多线程安全才不慌。
1.1 打开文件——一切操作的起点
Python里打开文件用open()函数。它的基本用法是这样的:
file = open('example.txt', 'r') # 'r' 表示只读模式
这里第一个参数是文件路径,第二个参数是打开模式。模式这块我建议你记牢,因为选错了模式,轻则报错,重则把文件内容搞丢。
| 模式 | 含义 | 文件指针位置 | 文件不存在时 |
|---|---|---|---|
| 'r' | 只读 | 开头 | 报错 |
| 'w' | 只写 | 开头 | 创建新文件 |
| 'a' | 追加 | 末尾 | 创建新文件 |
| 'x' | 独占创建 | 开头 | 创建新文件 |
| 'r+' | 读写 | 开头 | 报错 |
| 'w+' | 读写 | 开头 | 创建新文件 |
| 'a+' | 读写(追加模式) | 末尾 | 创建新文件 |
1.2 读取文件——把数据拿到内存里
文件打开后,怎么读?Python给了我们几种方式:
# 方式一:一次性读取全部内容
content = file.read()
print(content)
# 方式二:按行读取,返回列表
lines = file.readlines()
for line in lines:
print(line.strip())
# 方式三:逐行读取(推荐,省内存)
for line in file:
print(line.strip())
我个人习惯用第三种方式。为什么呢?你想想看,如果文件有10GB,用read()一次性读完,内存直接爆炸。而逐行读取,一次只处理一行,内存占用几乎可以忽略不计。
file.readline() 配合循环,或者用 for line in file 这种迭代器方式。我在处理服务器日志时,经常遇到几百MB甚至几个GB的文件,逐行读取是唯一靠谱的方案。
1.3 写入文件——把数据存到磁盘上
写入文件同样简单,但有几个坑要注意:
# 写入字符串
file.write('Hello, World!\n')
# 写入多行
lines = ['第一行\n', '第二行\n', '第三行\n']
file.writelines(lines)
这里有个细节——write() 不会自动加换行符。我记得刚学的时候,写了好几行数据,结果发现全挤在一行里。后来才明白,换行符得自己加。
另外,写入模式的选择也很关键:
- 'w' 模式:每次打开都会清空文件,从头开始写。适合覆盖旧数据。
- 'a' 模式:在文件末尾追加内容,不会清空原有数据。适合写日志。
flush() 或 close() 时,才会真正写入。这就是为什么程序崩溃时,最后写的数据可能会丢失。
1.4 关闭文件——别忘了解放资源
文件用完后,一定要关闭。为什么?因为操作系统对同时打开的文件数量有限制。我见过一个同事,写了个循环打开文件但不关闭,结果跑到第1024次时程序直接崩溃。
file = open('example.txt', 'r')
# ... 各种操作 ...
file.close() # 手动关闭
但手动关闭有个问题——如果中间代码报错了,close() 可能根本执行不到。所以Python推荐用 with 语句:
with open('example.txt', 'r') as file:
content = file.read()
# 操作完成后,自动关闭文件
# 这里文件已经关闭了
用 with 的好处是,不管代码执行成功还是报错,文件都会自动关闭。说白了,这就是Python帮你兜底了。
with,也要确保缩进正确。我曾经把 with 块内的代码写到了外面,结果文件提前关闭了,后面的读取操作全报错。
1.5 知识体系总览
下面这张图,把文件操作的核心流程串起来了。我建议你多看几遍,把每个环节的要点记牢。
1.6 避坑指南——我踩过的那些雷
最后,分享几个我实际项目中遇到的坑,希望能帮你少走弯路:
- 文件路径问题:Windows用反斜杠
\,Linux用正斜杠/。我建议统一用正斜杠,或者用os.path.join()自动处理。 - 编码问题:打开文件时指定编码,比如
open('file.txt', 'r', encoding='utf-8')。不然遇到中文可能直接报错。 - 文件不存在:用 'r' 模式打开不存在的文件会报错。可以先判断文件是否存在,或者用 try-except 捕获异常。
- 缓冲区刷新:如果程序突然崩溃,缓冲区里的数据就丢了。关键数据可以手动调用
flush()。
with 语句。既省去了手动关闭的麻烦,又避免了资源泄漏。说白了,这就是Python的优雅之处——能自动做的事,绝不让你手动干。
好了,文件操作的基础就这些。记住核心流程:打开、操作、关闭。下一节咱们聊聊多线程环境下怎么安全地读写文件——那才是真正考验功底的地方。