下面我将为你详细讲解如何使用 Python 读取文件,从最基本的方法到更高级和安全的用法。

核心步骤
无论使用哪种方法,读取文件通常都遵循三个基本步骤:
- 打开文件: 使用
open()函数,获取一个文件对象。 - : 通过文件对象的方法(如
read(),readline(),readlines())来读取数据。 - 关闭文件: 使用
close()方法关闭文件,释放系统资源。
使用 with open(...) 语句 (强烈推荐)
这是现代 Python 中最推荐、最安全、最常用的方法,它会自动处理文件的关闭,即使在读取过程中发生错误,也能确保文件被正确关闭。
读取整个文件内容 (read())
read() 方法会一次性读取文件的全部内容到一个字符串中。
示例代码:
假设你有一个名为 my_file.txt 的文件,内容如下:
Hello, Python!
这是第二行。
这是第三行。
# 使用 'with open' 语句,它会自动关闭文件
# 'r' 表示读取模式,这是默认模式,可以省略
try:
with open('my_file.txt', 'r', encoding='utf-8') as f:
# 读取所有内容
content = f.read()
print("--- 读取全部内容 ---")
print(content)
print(f"内容的类型是: {type(content)}")
except FileNotFoundError:
print("错误:文件未找到,请检查文件名和路径是否正确。")
except Exception as e:
print(f"发生了一个错误: {e}")
输出:
--- 读取全部内容 ---
Hello, Python!
这是第二行。
这是第三行。
的类型是: <class 'str'>
逐行读取 (readline())
readline() 方法每次只读取文件的一行,包括末尾的换行符 \n。
示例代码:
try:
with open('my_file.txt', 'r', encoding='utf-8') as f:
print("--- 逐行读取 ---")
while True:
line = f.readline()
# readline() 返回空字符串,表示已到达文件末尾
if not line:
break
# 使用 .strip() 可以去除行首行尾的空白字符(包括换行符)
print(f"读取到一行: {line.strip()}")
except FileNotFoundError:
print("错误:文件未找到。")
输出:
--- 逐行读取 ---
读取到一行: Hello, Python!
读取到一行: 这是第二行。
读取到一行: 这是第三行。
读取所有行到一个列表 (readlines())
readlines() 方法会一次性读取文件的所有行,并将每一行作为一个元素,存入一个列表中。
示例代码:
try:
with open('my_file.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
print("--- 读取所有行到列表 ---")
print(lines)
print(f"列表的类型是: {type(lines)}")
# 遍历列表
print("\n遍历列表内容:")
for i, line in enumerate(lines):
print(f"第 {i+1} 行: {line.strip()}")
except FileNotFoundError:
print("错误:文件未找到。")
输出:
--- 读取所有行到列表 ---
['Hello, Python!\n', '这是第二行,\n', '这是第三行,\n']
列表的类型是: <class 'list'>
第 1 行: Hello, Python!
第 2 行: 这是第二行。
第 3 行: 这是第三行。
传统的 open() 和 close() (不推荐)
这种方法需要你手动调用 close() 来关闭文件,如果忘记关闭,可能会导致资源泄漏,特别是在处理大量文件或长时间运行的程序中。
# 不推荐的方式,容易忘记关闭文件
f = None # 初始化 f,以防在 try 块之前就出错
try:
f = open('my_file.txt', 'r', encoding='utf-8')
content = f.read()
print(content)
finally:
# 使用 finally 块来确保文件无论如何都会被关闭
if f:
f.close()
为什么 with 更好?
with open(...) as f: 语句等同于上面的 try...finally... 结构,但代码更简洁、更易读,并且是 Pythonic 的写法。
重要参数说明
open() 函数有几个重要的参数:
-
mode(模式): 指定打开文件的模式。'r': 读取 (默认),如果文件不存在,会抛出FileNotFoundError。'w': 写入,如果文件存在,会先清空文件内容,如果文件不存在,会创建新文件。'a': 追加,在文件末尾写入内容,如果文件不存在,会创建新文件。'b': 二进制模式,用于处理非文本文件(如图片、视频、音频)。'rb'(读取二进制),'wb'(写入二进制)。- 读写模式。
'r+'(读写),'w+'(读写,会先清空)。
-
encoding(编码): 指定文件的字符编码。- 对于处理包含中文或其他非英文字符的文件,
encoding='utf-8'是最常用、最安全的选择。 - 如果不指定,Python 会使用系统的默认编码,这在不同环境下可能会导致乱码。
- 对于处理包含中文或其他非英文字符的文件,
处理大型文件
如果文件非常大(例如几个 GB),使用 f.read() 或 f.readlines() 会一次性将所有内容加载到内存中,可能导致内存耗尽。
对于大文件,最佳实践是逐行处理,因为内存中任何时候只有一行数据。
# 处理大型文件的最佳方式
line_count = 0
try:
with open('very_large_file.txt', 'r', encoding='utf-8') as f:
for line in f: # 直接迭代文件对象,它会自动逐行读取
line_count += 1
# 在这里处理每一行,
# if "error" in line:
# print(f"在第 {line_count} 行发现错误: {line.strip()}")
print(f"文件处理完毕,总共有 {line_count} 行。")
except FileNotFoundError:
print("错误:文件未找到。")
| 场景 | 推荐方法 | 说明 |
|---|---|---|
| 读取整个小文件 | with open(...) as f: content = f.read() |
简单直接,一次性获取所有内容。 |
| 逐行处理(大/小文件) | with open(...) as f: for line in f: |
最通用、最安全的方法,尤其适合大文件。 |
| 将所有行存入列表 | with open(...) as f: lines = f.readlines() |
便于后续随机访问某一行,但会占用较多内存。 |
| 传统方式 | f = open(...); ...; f.close() |
不推荐,容易出错,应使用 with 语句代替。 |
始终使用 with open(...) 并指定 encoding='utf-8',这会让你的文件操作代码更健壮、更可靠。
