• python中StringIO和BytesIO


    1. 类文件对象

    最常见的io操作是将磁盘中的文件读到内存以及内存内容写入文I件。还有一种内存和内存之间的IO,叫类文件对象,python中的StringIOBytesIO就是类文件对象,通俗解释即:像操作文件一样在内存中操作字符串和二进制内容
    磁盘上的文件,就是将数据持久化到磁盘的一块区域,供后面重复使用。其优点就是持久化稳定不丢失,但是缺点也很明显,就是每次要使用都要从磁盘读入,相对内存而言很缓慢。如果只是短时间的重复利用,并不希望长期持久化,而且对速度的要求比较高,这时候就可以考虑缓存。

    2. StringIO

    这种类文件对象是用来存储字符串的,下面展示了如何使用

    from io import StringIO, BytesIO
    
    if __name__ == "__main__":
        # 初始化并写入内容
        # io_obj = StringIO("i love china")
        # 初始化io
        io_obj = StringIO()
        # 写入内容
        io_obj.write("i love china")
        # 读取io中内容
        content = io_obj.read()
        # 返回:空
        print(content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    如上打印结果为空,这是因为内存中的对象有一个标志位的概念,往里面写入,标志位后移到下一个空白处。而读数据的时候是从标志位开始读,所以想要读取前面的数据需要手动将标志位进行移动。
    如下,通过seek方法将标志位移动到到首位,再读取内容就会读出所有内容;将seek中的0换成2会发现会舍弃前面两个字符。

        io_obj = StringIO()
        # 写入内容
        io_obj.write("i love china")
        # 将标志位移动到首位
        io_obj.seek(0)
        # 读取io中内容
        content = io_obj.read()
        # 返回:i love china
        print(content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    通过getvalue()方法获取全部内容,该方法不受标志位影响。注意,当我们在初始化io时同时写入内容io_obj = StringIO("i love china"),此时读取内容也不受标志位影响

        io_obj = StringIO()
        # 写入内容
        io_obj.write("i love china")
        # 读取io中内容
        content = io_obj.getvalue()
        # 返回:i love china
        print(content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    该对象使用完毕直接关掉,该内存里的内容被清空

    io_obj.close()
    
    • 1

    3. BytesIO

    StringIO只能存储字符串,对于图片视频等Bytes类型的内容就需要用到专门存储Bytes类型的BytesIO对象,用法完全相同,即:write()写内容,read()读内容,getvalue()获取所有内容…

    	# 初始化io
        io_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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.应用

    下面展示直接从网络读取一张图片,而不需要将图片保存到本地,再读本地文件

        import requests
        from PIL import Image
        response = 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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    返回结果
    在这里插入图片描述
    注意:此处我们无法直接把下载的Bytes类型用Image打开,Image接受的参数是一个文件对象,或者类文件对象。所以要么是磁盘上的文件,要么是内存中的BytesIO

  • 相关阅读:
    java执行shell命令,Runtime.exec()和jsch谁更有优势?
    笔记·Pandas几类数据读写方法对比
    工业控制系统安全标准
    kubelet存储插件初入
    uni-app去除页面头部的标题栏
    TypeError: list indices must be integers or slices, not tuple 错误原因解决方法
    java-net-php-python-springboot天山雪豹足球俱乐部信息管理系统计算机毕业设计程序
    QT 发布软件基本操作
    ReACT介绍与llama_index ReActAgent实践
    应用层协议 -- HTTPS 协议
  • 原文地址:https://blog.csdn.net/orangerfun/article/details/127974610