文件对象方法参考
假设已通过 f = open('test.txt', 'r+') 获得文件对象 f,以下是完整的文件对象 API。
文件对象方法速查表
读取类方法
| 方法 | 作用 | 返回值 | 关键特性 |
|---|---|---|---|
f.read(size=-1) | 读取内容 | 字符串/字节 | size=-1 读全部,否则读指定字符/字节数 |
f.readline(size=-1) | 读单行 | 字符串/字节 | 保留换行符 \n,size 限制本行最大读取量 |
f.readlines(hint=-1) | 读所有行 | 列表 | 每行是列表一个元素,hint 限制近似总字符数 |
f.__next__() | 迭代下一行 | 字符串 | 文件对象本身是迭代器 |
写入类方法
| 方法 | 作用 | 注意点 |
|---|---|---|
f.write(string) | 写入字符串/字节 | 返回写入的字符/字节数 |
f.writelines(lines) | 写入序列 | 不会自动添加换行符,需手动加 \n |
指针与文件状态
| 方法 | 作用 | 参数说明 |
|---|---|---|
f.seek(offset, whence=0) | 移动指针 | whence: 0=文件开头, 1=当前位置, 2=文件末尾 |
f.tell() | 返回当前指针位置 | 字节偏移量(文本模式下同样以字节计) |
f.truncate(size=None) | 截断文件 | 从当前位置或指定 size 截断,后续内容删除 |
f.flush() | 强制刷盘 | 将缓冲区数据立即写入磁盘,文件保持打开 |
f.close() | 关闭文件 | 释放资源,之后任何操作抛 ValueError |
属性与查询
| 属性/方法 | 作用 |
|---|---|
f.closed | 布尔值,文件是否已关闭 |
f.mode | 打开模式(如 'r'、'w+b') |
f.name | 文件名 |
f.encoding | 文本编码(文本模式);二进制模式为 None |
f.errors | 编码错误处理策略 |
f.newlines | 实际读取到的换行符类型(\n、\r\n、\r 或元组) |
f.readable() | 是否可读 |
f.writable() | 是否可写 |
f.seekable() | 是否支持随机访问(管道、tty 等返回 False) |
方法详解与边缘案例
1. read(size) 的精确行为
with open('example.txt', 'r', encoding='utf-8') as f:
# 文本模式:size 是字符数,不是字节数
chunk = f.read(10) # 读 10 个字符(可能对应 10–30 字节,取决于编码)
with open('example.bin', 'rb') as f:
# 二进制模式:size 是字节数
chunk = f.read(1024) # 读 1024 字节
2. readline() 与迭代器的区别
with open('data.txt', 'r') as f:
# 显式调用 readline()
line = f.readline()
while line:
print(line, end='') # line 已含 \n,end='' 避免多余空行
line = f.readline()
f.seek(0)
# 文件对象作为迭代器(更 Pythonic,内部有缓冲区优化)
for line in f:
print(line, end='')
f.seek(0)
# readlines():一次读入内存,适合小文件
lines = f.readlines() # ['第一行\n', '第二行\n']
关键区别:
-
readline()返回空字符串''表示 EOF -
迭代器在 EOF 时抛出
StopIteration(for循环自动处理)
3. writelines() 的陷阱
lines = ['第一行', '第二行', '第三行']
with open('output.txt', 'w') as f:
f.writelines(lines) # 结果:"第一行第二行第三行"(无换行符)
# 正确做法:手动添加换行符
with open('output.txt', 'w') as f:
f.writelines(line + '\n' for line in lines)
# 或 f.write('\n'.join(lines))
4. seek() 的高级用法
with open('data.bin', 'r+b') as f:
f.seek(100) # 跳到第 100 字节(从 0 开始)
f.seek(50, 1) # 从当前位置再向后 50 字节
f.seek(-10, 2) # 文件末尾前 10 字节
文本模式下的 seek 限制:
with open('utf8.txt', 'r', encoding='utf-8') as f:
f.read(10)
pos = f.tell() # 记录当前字节位置
f.seek(pos) # 安全:回到已记录的位置
f.seek(5) # 危险:可能落在多字节字符中间,引发解码错误
5. truncate() 截断文件
with open('log.txt', 'r+') as f:
f.read(100) # 移动指针到第 100 字节
f.truncate() # 删除第 100 字节之后的所有内容
截断到指定大小(二进制模式更可靠):
with open('log.txt', 'r+b') as f:
f.truncate(50) # 文件缩减为前 50 字节
6. flush() 与操作系统缓冲
import time
with open('realtime.log', 'w') as f:
f.write('关键日志')
f.flush() # 刷新 Python 缓冲区,写入操作系统缓冲
# os.fsync(f.fileno()) # 更极端:强制物理写入磁盘(性能损耗较大)
time.sleep(10)
7. 文件对象的关闭状态
f = open('test.txt', 'w')
print(f.closed) # False
f.close()
print(f.closed) # True
# f.read() # ValueError: I/O operation on closed file.
实战模式:方法组合示例
模式 1:大文件逐块处理
def process_large_file(filepath, callback, chunk_size=8192):
with open(filepath, 'r', encoding='utf-8') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
callback(chunk)
print(f"已处理至字节位置:{f.tell()}")
模式 2:原地修改文件(适合小文件)
def insert_at_position(filepath, position, text):
with open(filepath, 'r+', encoding='utf-8') as f:
f.seek(position)
remaining = f.read()
f.seek(position)
f.write(text)
f.write(remaining)
f.truncate()
模式 3:读取后覆盖写入
with open('data.txt', 'r+', encoding='utf-8') as f:
content = f.read()
new_content = content.upper()
f.seek(0)
f.write(new_content)
f.truncate() # 新内容比旧内容短时,删除尾部残留
易错点总结
| 易错点 | 说明 |
|---|---|
readlines() 不是 read_lines() | 无下划线;返回的列表每个元素包含换行符 |
write() 不自动换行 | 与 print() 不同,write() 不会自动添加 \n |
文本模式 seek 危险 | 不要跳到任意字节位置,应始终使用 tell() 的返回值 |
flush() 不等于 close() | flush() 后文件仍可用;close() 后彻底失效 |
readlines() 结果含换行符 | 遍历时需 .strip() 或 .rstrip('\n') 去除 |