文件读写方法
文件对象提供了一系列方法用于读取和写入数据。根据需求选择合适的方法,可以显著提高效率和代码清晰度。
读取方法
read(size=-1):读取全部或指定字节/字符
f = open("data.txt", "r")
# 读取全部内容
content = f.read()
print len(content) # 文件总长度
# 读取指定字节数
chunk = f.read(100) # 读取最多 100 字节
read() 返回字符串(文本模式)或字节串(二进制模式)。大文件用 read() 会一次性加载到内存,可能耗尽 RAM。
readline():读取一行(包含末尾的换行符 \n)
f = open("data.txt", "r")
line = f.readline()
print repr(line) # 'First line\n'
line = f.readline()
print repr(line) # 'Second line\n'
line = f.readline()
print repr(line) # ''(空字符串表示 EOF)
readlines():读取所有行,返回列表
f = open("data.txt", "r")
lines = f.readlines()
print lines # ['First line\n', 'Second line\n', 'Third line\n']
readlines() 可以指定 sizehint 参数,读取大约这么多字节(非精确值):
lines = f.readlines(1024) # 读取约 1KB 的内容
逐行迭代(推荐):
f = open("data.txt", "r")
for line in f:
print line.strip() # 去除换行符
这是读取大文件最内存高效的方式——每次只加载一行到内存,而非整个文件。
写入方法
write(string):写入字符串
f = open("output.txt", "w")
f.write("Hello, world\n")
f.write("Second line\n")
f.close()
write() 不自动添加换行符,需要手动写入 \n。
writelines(lines):写入序列
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
f = open("output.txt", "w")
f.writelines(lines)
f.close()
writelines() 不会自动添加换行符,序列中的每个元素必须已经包含 \n。
文件定位
文件对象维护一个"文件指针",记录当前读写位置。
tell():返回当前位置
f = open("data.txt", "r")
print f.tell() # 0,开头
f.read(10)
print f.tell() # 10
seek(offset, whence=0):移动文件指针
f = open("data.txt", "r")
f.seek(0) # 移动到开头(whence=0,默认)
f.seek(10) # 移动到第 10 字节
f.seek(-5, 2) # 从末尾向前移动 5 字节(whence=2)
f.seek(5, 1) # 从当前位置向前移动 5 字节(whence=1)
whence 参数:
0(默认):从文件开头计算1:从当前位置计算2:从文件末尾计算
⚠️ 文本模式下,seek() 的行为在 Windows 上可能不符合预期(因为 \r\n 被转换为 \n)。二进制模式下 seek() 最可靠。
实际应用
读取大文件:
# 方法 1:逐行迭代(最省内存)
with open("huge_file.txt", "r") as f:
for line in f:
process(line)
# 方法 2:分块读取
with open("huge_file.txt", "r") as f:
while True:
chunk = f.read(8192) # 8KB 一块
if not chunk:
break
process(chunk)
追加日志:
with open("app.log", "a") as f:
f.write("[%s] %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S"), message))
复制文件:
with open("source.bin", "rb") as src:
with open("dest.bin", "wb") as dst:
while True:
chunk = src.read(4096)
if not chunk:
break
dst.write(chunk)
文件对象的属性
f = open("data.txt", "r")
print f.name # data.txt
print f.mode # r
print f.closed # False
f.close()
print f.closed # True
常见错误
在关闭后操作:
f = open("data.txt", "r")
f.close()
f.read() # ValueError: I/O operation on closed file
在文本模式下处理二进制数据:
f = open("image.jpg", "r") # 应该用 "rb"!
data = f.read()
# 图片数据可能被损坏(Windows 上 \r\n 被转换)
忘记处理换行符:
for line in f:
if line == "target": # 永远不会匹配!line 包含 \n
pass
# 正确做法
for line in f:
if line.strip() == "target":
pass