纳速健身

标题: python3.x中StringIO与BytesIO的介绍与用法 [打印本页]

作者: awagink    时间: 2020-8-27 09:24
标题: python3.x中StringIO与BytesIO的介绍与用法
总结:io.StringIO读取字符串或文件,io.BytesIO读取图片。
StringIO经常被用来作字符串的缓存,因为StringIO的一些接口和文件操作是一致的,也就是说同样的代码,可以同时当成文件操作或者StringIO操作。StringIO的行为与file对象非常像,但它不是磁盘上文件,而是一个内存里的“文件”,我们可以将操作磁盘文件那样来操作StringIO。一个简单的例子,让你对StringIO有一个感性的认识:

import io
#生成一个StringIO对象,
s = io.StringIO()
#write()从读写位置将参数s写入到对象s,参数为str或unicode类型,读写位置被移动
s.write('Hello World\n')
#getvalue()用法:返回对象s中的所有数据
print(s.getvalue())
# read(n)用法:参数n用于限定读取的长度,类型为int,默认为从当前位置读取对象s中所有的数据。读取结束后,位置被移动。
s = io.StringIO('Hello World\n')
print(s.read(1))
#结果 H
print(s.read())
#结果 ello World
s = io.StringIO('Hello World\n')
#readline(length)用法:length用于限定读取的结束位置,类型为int,缺省为None,即从当前位置读取至下一个以'\n'为结束符的当前行。读位置被移动。
print(s.readline(7))
#结果 Hello W
s = io.StringIO('Hello\n World\n')
print(s.readline(7))
#结果 Hello
a = '''
Hello
World
this
is
a
tes
'''
# readlines用法::读取所有行.,返回一个列表,会把换行符给读取出来,,
s = io.StringIO(a)
print(s.readlines())
#结果['\n', 'Hello\n', 'World\n', 'this\n', 'is\n', 'a\n', 'tes\n']
# StringIO还有一个对应的c语言版的实现,它有更好的性能,但是稍有一点点的区别:
# cStringIO没有len和pos属性。(还有,cStringIO不支持Unicode编码)
# 如果实例化一个带有默认数据的cStringIO.StringIO类。那么该实例是read-only的;
# 无默认参数的是cStringIO.StringO,它是可读写的。cs = cStringIO.StringO()
# StringIO模块主要用于在内存缓冲区中读写数据。模块是用类编写的,只有一个StringIO类,
# 所以它的可用方法都在类中。此类中的大部分函数都与对文件的操作方法类似。
#利用BytesIO 获取图片的大小格式,

import io
from PIL import Image  # 注意我的Image版本是pip3 install Pillow==4.3.0
import requests
res = requests.get('http://p99.pstatp.com/large/pgc-image/95b9aa2664c1441199795f84e2812e39.jpg', stream=True)  # 获取字节流最好加stream这个参数,原因见requests官方文档
byte_stream = io.BytesIO(res.content)  # 把请求到的数据转换为Bytes字节流(这样解释不知道对不对,可以参照有管的教程看一下)
roiImg = Image.open(byte_stream)   # Image打开Byte字节流数据
print(roiImg.format)       # 获取图片的格式
print(roiImg.size)         #获取图片的大小
imgByteArr = io.BytesIO()     # 创建一个空的Bytes对象
imgByteArr = imgByteArr.getvalue()   # 这个就是保存的图片字节流



下面举例:

StringIO
很多时候,数据读写不一定是文件,也可以在内存中读写。

StringIO顾名思义就是在内存中读写str。

要把str写入StringIO,我们需要先创建一个StringIO,然后,像文件一样写入即可:

>>> from io import StringIO
>>> f = StringIO()
>>> f.write('hello')
>>> f.write(' ')
>>> f.write('world!')
>>> print(f.getvalue())
hello world!
getvalue()方法用于获得写入后的str。

要读取StringIO,可以用一个str初始化StringIO,然后,像读文件一样读取:

>>> from io import StringIO
>>> 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:

>>> from io import BytesIO
>>> f = BytesIO()
>>> f.write('中文'.encode('utf-8'))
>>> print(f.getvalue())
b'\xe4\xb8\xad\xe6\x96\x87'

请注意,写入的不是str,而是经过UTF-8编码的bytes。

和StringIO类似,可以用一个bytes初始化BytesIO,然后,像读文件一样读取:

>>> 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的方法,使得和读写文件具有一致的接口。

参考源码
do_stringio.py
do_bytesio.py







欢迎光临 纳速健身 (https://nasue.com/) Powered by Discuz! X3.4