1. 类文件对象
最常见的io操作是将磁盘中的文件读到内存以及内存内容写入文I件。还有一种内存和内存之间的IO,叫类文件对象,python中的StringIO
和BytesIO
就是类文件对象,通俗解释即:像操作文件一样在内存中操作字符串和二进制内容
磁盘上的文件,就是将数据持久化到磁盘的一块区域,供后面重复使用。其优点就是持久化稳定不丢失,但是缺点也很明显,就是每次要使用都要从磁盘读入,相对内存而言很缓慢。如果只是短时间的重复利用,并不希望长期持久化,而且对速度的要求比较高,这时候就可以考虑缓存。
2. StringIO
这种类文件对象是用来存储字符串的,下面展示了如何使用
from io import StringIO, BytesIOif __name__ == "__main__":# 初始化并写入内容# io_obj = StringIO("i love china")# 初始化ioio_obj = StringIO()# 写入内容io_obj.write("i love china")# 读取io中内容content = io_obj.read()# 返回:空print(content)
如上打印结果为空,这是因为内存中的对象有一个标志位的概念,往里面写入,标志位后移到下一个空白处。而读数据的时候是从标志位开始读,所以想要读取前面的数据需要手动将标志位进行移动。
如下,通过seek方法将标志位移动到到首位,再读取内容就会读出所有内容;将seek中的0换成2会发现会舍弃前面两个字符。
io_obj = StringIO()# 写入内容io_obj.write("i love china")# 将标志位移动到首位io_obj.seek(0)# 读取io中内容content = io_obj.read()# 返回:i love chinaprint(content)
通过getvalue()
方法获取全部内容,该方法不受标志位影响。注意,当我们在初始化io时同时写入内容io_obj = StringIO("i love china")
,此时读取内容也不受标志位影响
io_obj = StringIO()# 写入内容io_obj.write("i love china")# 读取io中内容content = io_obj.getvalue()# 返回:i love chinaprint(content)
readline()
方法读取以\n
为界的一行数据,readlines()
读取所有行,注意标志位置零
io_obj = StringIO()# 写入内容io_obj.write("i love china\n wo ai zhongguo")# 读取io中内容io_obj.seek(0)# content = io_obj.readline()# 返回:i love china# print(content)content_all = io_obj.readlines()# 返回所有行:['i love china\n', ' wo ai zhongguo']print(content_all)
该对象使用完毕直接关掉,该内存里的内容被清空
io_obj.close()
3. BytesIO
StringIO只能存储字符串,对于图片视频等Bytes类型的内容就需要用到专门存储Bytes类型的BytesIO对象,用法完全相同,即:write()
写内容,read()
读内容,getvalue()
获取所有内容…
# 初始化ioio_obj = BytesIO()io_obj.write("i love china".encode("utf-8"))io_obj.seek(0)content = io_obj.read()# 返回:b'i love china'print(content)
4.应用
下面展示直接从网络读取一张图片,而不需要将图片保存到本地,再读本地文件
import requestsfrom PIL import Imageresponse = requests.get('https://ts1.cn.mm.bing.net/th/id/R-C.fd4056c8c00979ab8561f8db8219c2ae?rik=JPk67EIYaKIS3A&riu=http%3a%2f%2fimg.mm4000.com%2ffile%2fa%2fa2%2f869bd2bd6a.jpg&ehk=2z%2bPuRHJOYtkm9ICs8fPs0EJbE96jJX2E8QyrVP5kyQ%3d&risl=&pid=ImgRaw&r=0')img = BytesIO()img.write(response.content)pict = Image.open(img)pict.show()img.close()
返回结果
注意:此处我们无法直接把下载的Bytes类型用Image打开,Image接受的参数是一个文件对象,或者类文件对象。所以要么是磁盘上的文件,要么是内存中的BytesIO