第95天:StringIO & BytesIO

上一篇中我们介绍了文件的基本读写操作,但是很多时候数据的读写并不一定都是在文件中,我们也可以在内存中读写数据,因此引出我们今天的主要内容,即 StringIO 和 BytesIO,让你学会在内存中进行数据的基本读写操作。

1 前言-内存与硬盘

在正式介绍 StringIO 和 BytesIO 之前,我们先来了解一下内存和硬盘的差异,以便更好的理解硬盘中文件的基本操作与 StringIO 和 BytesIO 对数据的基本操作两者之间存在的意义。

内存与硬盘的差异:

差异点 内存 硬盘
形状 长条形,所以有内存条之称 四四方方的,内含盘片
容量(以 PC 机为例) 4G 1T
功能 存储任务管理器的进程 存储文档、软件等数据
运行速度
特点 存放 CPU 运算的数据,一旦断电数据就会消失 可以永久存储数据

通俗点来讲,我们电脑里的 C 盘、D盘等都是硬盘,电脑关机后再次开机这些盘符里面的数据依然还在。但是我们电脑任务管理器里面跑的进程的数据都是存储在内存中的,电脑关机后进程里面的数据就不复存在了。

正是由于硬盘的读取数据比较慢,CPU 如果在运行程序的时候所有数据都直接从硬盘中读写,那么电脑的运行速度将会大打折扣。因此 CPU 会将运行软件时要用到的数据一次性从硬盘中调到运行速度很快的内存中,然后 CPU 再与内存进行数据交换。一个很明显的现象就是我们在打开一个软件时会有一段时间延迟,但是打开之后软件的运行速度就很快了。

好了,现在我们应该对在内存与硬盘上读取数据大概有一个了解,开始进入我们的正题。

2 StringIO 和 BytesIO

StringIO 和 BytesIO 的作用简单来说,就是在内存中虚拟一个文件的感觉,这个虚拟出来的文件操作方式与上一篇介绍的在硬盘中文件的基本操作类似。在 Python3 中,这两“兄弟”现在已经归入 IO 模块。

2.1 StringIO

要把 str 字符串写入内存中,我们需要创建一个 StringIO 对象,然后像文件一样对读取内容。其中 StringIO 中多了一个 getvalue() 方法,目的是用于获取写入后的 str。

示例 1:

# 定义一个 StringIO 对象,写入并读取其在内存中的内容from io import StringIO
f = StringIO()
f.write('Python-100')str = f.getvalue()print('写入内存中的字符串为:%s' %str)
f.write('\n') # 追加写入内容f.write('坚持100天')str = f.getvalue() # getvalue() 可以读取到 StringIO 中的所有内容print('写入内存中的字符串为:\n%s' %str)
f.close() # 释放内存中的数据,后续不可再对该 StringIO 进行内容的读写操作
# 输出结果# 写入内存中的字符串为:# Python-100# 写入内存中的字符串为:# Python-100# 坚持100天

示例 2:

# 当然也可以用 read()、readline() 等来读取 StringIO 中写入的字符串
from io import StringIO
str = 'Python-100' + '\n' + '坚持100天'
f = StringIO(str)
currentStr = f.read()print('写入内存中的字符串为:\n%s' %currentStr)
f.close()

示例 3:

# 考虑一个场景,比如你需要对爬虫爬取到的数据进行操作,但是你不想把数据写入本地的硬盘上,这时候 StringIO 就派上用场了。
from io import StringIO
# 假设的爬虫数据输出函数 outputData()def outputData(): dataOne = '我是 1 号爬虫数据\n' dataTwo = '我是 2 号爬虫数据\n' dataThree = '我是 3 号爬虫数据' data = dataOne + dataTwo + dataThree return data
# dataStr 为爬虫数据字符串dataStr = outputData()
# 1. 将 outputData() 函数返回的内容写入内存中dataIO = StringIO(dataStr)
# 1.1 输出 StringIO 在内存中写入的数据print('1.1内存中写入的数据为:\n%s' %dataIO.getvalue())
# 输出结果:# 1.1内存中写入的数据为:# 我是 1 号爬虫数据# 我是 2 号爬虫数据# 我是 3 号爬虫数据
# 1.2 按行输出写入的数据方式一print('1.2按行输出写入的数据方式一:')for data in dataIO.readlines(): print(data.strip('\n')) # 去掉每行数据末尾的换行符
# 输出结果:# 1.2按行输出写入的数据方式一:# 我是 1 号爬虫数据# 我是 2 号爬虫数据# 我是 3 号爬虫数据
# 1.3 按行输出写入的数据方式二# 由于上一步的操作,此时文件指针指向数据末尾(32),我们需要将指针指向起始位置print('由于上一步操作的输出,此时文件指针位置为:%d' %dataIO.tell())
# 将文件指针指向起始位置,方便下面的演示dataIO.seek(0)print('1.3按行输出写入的数据方式二:')for data in dataIO: print(data.strip('\n'))
# 输出结果:# 1.3按行输出写入的数据方式二:# 我是 1 号爬虫数据# 我是 2 号爬虫数据# 我是 3 号爬虫数据
# 2. 采用 write() 的方法将字符串写入内存dataWriteIO = StringIO()dataWriteIO.write(dataStr)
# 2.1 输出内存中写入的数据print('2.1内存中写入的数据为:\n%s' %dataIO.getvalue())
# 输出结果:# 2.1内存中写入的数据为:# 我是 1 号爬虫数据# 我是 2 号爬虫数据# 我是 3 号爬虫数据 # 2.2 按行输出写入的数据方式一# 由于 write() 写入字符串后,文件指针会指向写入内容的结尾,需要将文件指针指向起始位置,否则未能输出内容print('2.2按行输出写入的数据方式一:')print('输出内容为空!')for data in dataIO: print(data.strip('\n'))print('输出内容为空!')
# 输出结果:# 2.2按行输出写入的数据方式一:# 输出内容为空!# 输出内容为空!

# 2.3 按行输出写入的数据方式二# 将指针指向起始位置重新按行输出dataIO.seek(0)print('2.3按行输出写入的数据方式:')for data in dataIO.readlines(): print(data.strip('\n'))
# 输出结果# 2.3按行输出写入的数据方式:# 我是 1 号爬虫数据# 我是 2 号爬虫数据# 我是 3 号爬虫数据

Tips: 根据这个例子可以看出,当我们使用 StringIO(str) 方法向内存写入数据时,文件指针是指向起始位置的,比如示例 3 的 1.2 场景中 readlines() 可以读取到数据。当我们使用 write(str) 方法向内存写入数据时,文件指针会指向写入内容的结尾,读取数据时需要将指针移动到起始位置,比如示例 3 的 2.3 场景。

2.2 BytesIO

BytesIO,顾名思义,就是将字节流写入到内存中,其实它的操作方法与 StringIO 一样,区别就在于前者写入字节,后者写入字符串。这边就简单举个例子演示,不再具体介绍了。

示例:

# 定义一个 BytesIO 对象,写入并读取其在内存中的内容
from io import BytesIO
str = 'Python-100' + '\n' + '坚持100天'
f = BytesIO(str.encode('utf-8'))
print('写入内存的字节为:%s' %f.getvalue())
print('字节解码后内容为:\n%s' %f.getvalue().decode('utf-8'))

Tips: 根据示例可知,对于字节我们需要掌握其正确的编解码方式,比如有 'utf-8'、'gbk' 等。

3 总结

本节给大家介绍了 Python 中 StringIO 和 BytesIO 的基本使用方法,掌握在内存中存取数据的基本操作,同时介绍了内存与硬盘的区别,让大家明白在内存中存取数据的优势,助力您在爬虫的道路越走越远。

示例代码:https://github.com/JustDoPython/python-100-day

参考资料

https://www.cnblogs.com/minseo/p/11164921.html

https://www.liaoxuefeng.com/wiki/1016959663602400/1017609424203904

系列文章

第94天:数据分析之 pandas 初步
第93天:文件读写
第92天:Python Matplotlib 进阶操作
第91天:Python matplotlib introduction
从 0 学习 Python 0 - 90 大合集总结
(0)

相关推荐

  • 五分钟带你认识StringIO、BytesIO

    open()对文件进行读写已经很熟了,那么内存上的读写是怎么样的呢? 大邓对此只是了解了读写的皮毛,对CS基本不懂,但记忆力好,多动手多回顾就是了.好脑子不如多敲代码,敲代码不如多写文章分享,时刻记录 ...

  • 如何批量采集网页表格数据?

    Comming Soon! Python&Stata数据分析课寒假工作坊 我们最想要的数据格式就是表数据,但这表格并不是excel文件,而是存在于网页上的表数据.比如本教程实验网站 http: ...

  • python IO编程(文件读写、StringIO和BytesIO、操作文件和目录、序列化)

    学习目标: python学习十二. 学习内容: 1.文件读写 2.StringIO和BytesIO 3.操作文件和目录 4.序列化 1.文件读写 读写文件就是请求操作系统打开一个文件对象(通常称为文件 ...

  • 广华日志漫笔99977(95)

    为什么很多兄弟姐妹她迷恋于做视频,因为她的流量90%都是通过视频来的,为什么很多兄弟姐妹她迷恋于做音频,因为它的流量很多都是通过做音频来的,那为什么有很多兄弟姐妹迷恋于做文章,因为它的流量都是通过文章 ...

  • 别说95后不行了,他们真的很会生活

    当你搜索"95后为什么"的时候就会出现这些问题: "95后为什么不想结婚?" "95后为什么动不动就辞职?" "95后为什么不愿意 ...

  • 关晓彤、李庚希《二十不惑》官宣定档,聚焦95后的生活

    关晓彤.李庚希<二十不惑>官宣定档,聚焦95后的生活. 由黎志执导,关晓彤.卜冠今.李庚希.董思怡.金世佳.牛骏峰.王安宇.曹恩齐.徐绍瑛等共同出演的<二十不惑>官宣定档,该片 ...

  • 95岁老中医畅谈长寿经验:坚持4个习惯,身体越来越年轻

    中医理论是珍贵的精神财富,虽然时代不断变迁,中医的养生智慧依然值得很多现代人去学习.效仿.一些老中医对如何养生.延年益寿也有着自己的见解,下面就一起来看看吧. 老中医畅谈4个养生忠告,身体越来越年轻 ...

  • 领导力模型一览(95个)

    在寻找领导力模型时,我们发现了很多许多领导力模型.每个组织似乎都建立了领导模型,企业不用说,教堂,教育机构,政府,海岸警卫队和咨询公司,都有自己的领导力榜样. 经过研究,发现大多数领导力模型都以圆形显 ...

  • 辽沈战役当中,伤亡超95%的配水池攻坚战那么惨烈,为何非打不可

    解放战争时期,因带领全营取得配水池攻坚战的胜利,营长赵兴元被赋予了全国战斗英雄称号,随后的日子里,赵兴元的身边环绕着荣誉和鲜花:但是每当身边的人们问及赵兴元,配水池之战的实际情形之时,他却往往报以沉默 ...

  • 筹码获利比例大于95%选股公式

    编写条件: 筹码获利比例大于95%换手率大于3%,量比大于2%选股公式. 编写方法: A1:=WINNER(C)*100>95; A2:=VOL/CAPITAL*100>3; A3:=V/ ...