Python3 IO编程之StringIO和BytesIO
StringIO
很多时候,数据读写不一定是文件,也可以在内存中读写。
要把str写入StringIO,我们需要先创建一个StringIO,然后像文件一样写入即可
1 2 3 4 5 6 7 8 9 10 11 12 | >>> from io import StringIO >>> f = StringIO() >>> f.write( 'hello' ) 5 >>> f.write( ' ' ) 1 >>> f.write( 'world!' ) 6 >>> f <_io.StringIO object at 0x7f6bbc76e318 > >>> f.getvalue() 'hello world!' |
getvalue()方法用于获得写入后的str
要读取StringIO,可以用一个str初始化StringIO,然后像读文件一样读取
1 2 3 4 5 6 7 8 9 10 | >>> f = StringIO( 'Hello!\nHi!\nGoodbye!' ) >>> while True : ... s = f.readline() ... if s = = '': ... break ... print (s.strip()) ... Hello! Hi! Goodbye! |
BytesIO
StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。
BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes:
1 2 3 4 5 6 | >>> from io import BytesIO >>> f = BytesIO() >>> f.write( '中文' .encode( 'utf-8' )) 6 >>> f.getvalue() b '\xe4\xb8\xad\xe6\x96\x87' |
请注意,写入的不是str,而是经过UTF-8编码的bytes。
和StringIO类似,可以用一个bytes初始化BytesIO,然后,像读文件一样读取:
1 2 3 4 | >>> from io import BytesIO >>> f = BytesIO(b '\xe4\xb8\xad\xe6\x96\x87' ) >>> f.read() b '\xe4\xb8\xad\xe6\x96\x87' |
StringIO和BytesIO是在内存中操作str和bytes的方法,使得和读写文件具有一致的接口。
用一个列子加深对StringIO和BytesIO的理解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | # StringIO和BytesIO # stringIO 比如说,这时候,你需要对获取到的数据进行操作,但是你并不想把数据写到本地硬盘上,这时候你就可以用stringIO from io import StringIO from io import BytesIO def outputstring(): return 'string \nfrom \noutputstring \nfunction' s = outputstring() #s为字符串'string \nfrom \noutputstring \nfunction' #将函数返回的数据在内存中读 sio = StringIO(s) #可以用StringIO本身的方法 sio.getvalue() #输出 #'string \nfrom \noutputstring \nfunction' #也可以用file-like object的方法 s = sio.readlines() #readlines返回的是一个列表 #['string \n', 'from \n', 'outputstring \n', 'function'] for i in s: print (i.strip()) #去除尾部的回车符号输出 #string #from #outputstring #function #将函数返回的数据在内存中写 s = outputstring() sio = StringIO() sio.write(s) #如果是在终端会显示指针位置值36 #可以用StringIO本身的方法查看 print (sio.getvalue()) #如果你用file-like object的方法查看的时候,你会发现数据为空 #因为指针位置在尾部36 for i in sio.readlines(): print (i.strip()) #这时候我们需要修改下文件的指针位置 #就可以打印内容了 sio.seek( 0 , 0 ) #打印指针位置 print (sio.tell()) #结果为0 # 这就涉及到了两个方法seek 和 tell # tell 方法获取当前文件读取指针的位置 # seek 方法,用于移动文件读写指针到指定位置,有两个参数,第一个offset: 偏移量,需要向前或向后的字节数,正为向后,负为向前;第二个whence: 可选值,默认为0,表示文件开头,1表示相对于当前的位置,2表示文件末尾 # 用seek方法时,需注意,如果你打开的文件没有用'b'的方式打开,则offset无法使用负值哦 #在使用file-like object方法可以打印了 for i in sio.readlines(): print (i.strip()) # stringIO 只能操作str,如果要操作二进制数据,就需要用到BytesIO # 上面的sio无法用seek从当前位置向前移动,这时候,我们用'b'的方式写入数据,就可以向前移动了 bio = BytesIO() bio.write(s.encode( 'utf-8' )) #使用getvalue()方法quzhi print (bio.getvalue()) #b'string \nfrom \noutputstring \nfunction' #修改指针 #1代表从当前位置,-36代表往前移动36 bio.seek( - 36 , 1 ) bio.tell() #0 for i in bio.readlines(): print (i.strip()) |
注意:当使用StringIO去初始化的时候,其指针是指向0的位置,而如果是用write的方法的时候,其指针会移动到最后
举例如下
1 2 3 4 5 6 7 8 9 10 11 12 | >>> sio = StringIO( 'abc' ) >>> sio.getvalue() 'abc' >>> sio.tell() 0 #初始化指针指向0 值为'abc' >>> sio = StringIO( 'def' ) >>> sio.tell() 0 >>> sio.getvalue() 'def' #再次初始化会覆盖原值 |
对比write方法
1 2 3 4 5 6 7 8 9 10 11 12 13 | >>> a = StringIO() #写指针加3 >>> a.write( '123' ) 3 #再次写追加指针再加3 >>> a.write( '456' ) 3 #值为追加非覆盖 >>> a.getvalue() '123456' #最后指针为6 >>> a.tell() 6 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!