Python3 StringIO 与 BytesIO
StringIO 与 BytesIO 是 io 模块提供的"内存缓冲区":StringIO 把文本放在内存里模拟一个文件,BytesIO 把二进制数据放在内存里模拟一个文件。读写方式与真实文件完全一致,却不产生磁盘文件,适合字符串拼接、单元测试与临时数据处理。
StringIO:内存中的文本缓冲区
StringIO 相当于一个"住在内存里的文本文件"。用 write 写入、getvalue 一次性取出全部内容:
from io import StringIO
buf = StringIO() # 创建空的内存文本缓冲区
buf.write("你好,")
buf.write("Python!")
print(buf.getvalue()) # 输出:你好,Python!
与真实文件一致的接口
StringIO 与 open() 返回的文件对象接口相同,read、readline、seek、遍历等照常可用:
from io import StringIO
buf = StringIO("第一行\n第二行\n第三行") # 创建时就带内容
print(buf.readline()) # 输出:第一行
buf.seek(0) # 指针回到开头
for line in buf:
print(line.strip()) # 依次输出:第二行 / 第三行
两者的差别只在存储介质:文件对象把数据写到磁盘,StringIO 只占内存、用完即弃。
典型用途
- 拼接大量字符串:用 + 反复拼接会不断创建新字符串,先写入 StringIO 再一次性取出更高效;
- 单元测试:函数需要"类文件"参数时,传 StringIO 即可捕获写入内容,无需真的落盘:
from io import StringIO
def save_log(f, msg): # f 既可以是真实文件,也可以是 StringIO
f.write(f"[{msg}]")
out = StringIO()
save_log(out, "系统启动")
assert out.getvalue() == "[系统启动]" # 断言通过
print("测试通过") # 输出:测试通过
传给"类文件"接口
很多库的函数接受任何带 write() 方法的对象,此时 StringIO 可以顶替真实文件,把输出"接"进内存:
import json
from io import StringIO
out = StringIO()
json.dump({"ok": True, "n": 1}, out) # JSON 序列化到内存缓冲区
print(out.getvalue()) # 输出:{"ok": true, "n": 1}
同理,csv.writer、zipfile、logging 的 StreamHandler 等都可用 StringIO 承接,便于测试与二次处理。
BytesIO:二进制缓冲区
处理图片、压缩包等二进制数据时用 BytesIO,读写的是字节(bytes)而非字符串:
from io import BytesIO
data = BytesIO()
data.write(b"\x00\x01\x02") # 写入字节串
print(data.getvalue()) # 输出:b'\x00\x01\x02'
b = BytesIO(b"abcdef") # 从已有字节构造
print(b.read(3)) # 输出:b'abc'
小结:文本用 StringIO、二进制用 BytesIO,接口与真实文件一致且不占磁盘,适合拼接、测试与临时数据缓冲。