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,接口与真实文件一致且不占磁盘,适合拼接、测试与临时数据缓冲。

笔记加载中…