前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[技巧篇] 如何在不会的情况下解释 Python 设置文件的缓冲的问题

[技巧篇] 如何在不会的情况下解释 Python 设置文件的缓冲的问题

作者头像
编程文青李狗蛋
发布2019-09-17 16:19:28
6220
发布2019-09-17 16:19:28
举报
文章被收录于专栏:编程文青李狗蛋

美好的中秋,朋友圈在享受悠闲周末的时候,刚入门 Python 的程序员小R在公司埋头加班,不知时间几何,一不小心把下周的工作捯饬完了,心情愉悦,不能自拔。

这不,周一的早上,小R吹着口哨,泡着枸杞,幻想着划水到飞起,嘴角抑制不住的咧到了耳朵根儿,翘起了二郎腿。

正抖腿抖到舒坦的时候,微信收到了一条消息,点开一看,消息来自一个熟悉又陌生的名字,在记忆的排水沟里使劲掏了掏,好不容易对号入座。一个许久未曾联系的同学小K,消息只有两个字:

“在吗?”

看着这两个字, 小R眉头一皱,发现事情

怎么回事?他这是要干嘛?为什么要问在吗?

是要借钱嘛?是要结婚嘛?是要...

挣扎良久,小R放下了二郎腿,按下了键盘:

“在”

此时心里已经在自导自演各种应对场景:

“要是借钱,我就...”

“要是结婚,我就...”

“....”

有一条消息过来,在它闪动的第24 次小R打开了聊天窗口:“听说你是 Python 大佬,我有一个问题想问你。”

嘿,吓死我了,你早说啊,此时小R内心一阵窃喜:“哎呀,我这么低调,竟然被人发现大佬的身份啦,看来我还要再低调一点,哈哈哈哈哈哈...”

低调的小R低调的在窗口敲下了如下内容:

“哎呀,没有啦,你有什么问题,随便问,没有我不会的。”

enter 一键发送。

小K:“太好了,Python 里面怎么设置文件的缓冲啊?”

小R:“....”

文件我懂,缓冲我懂,怎么设置,我哪知道怎么设置...

小K:“还在吗?”

好想说不在,当然认真负责的小R当然不会这样,有句伟大的“名言”怎么说的来着:自己的低调,跪着也要低调完...

于是,小R默默的打开了 Google...


00.文件的缓冲

如何设置文件的缓冲,先要知道什么是文件的缓冲

当我们将文件内容写入到硬件设备的时候,我们需要系统调用(系统调用也就是向操作系统申请一个服务,操作系统响应以后,帮助我们调用硬件的驱动程序)来完成写操作,这类操作我们也就是 I/O 操作。I/O 操作很耗时,为了提高效率,我们就要减少 I/O 操作的次数,我们使用的手段就是为文件设置一个缓冲区。

对于磁盘这种块设备,它的读写不是一个一个的字节,而是按“块”。假设一个“块”的大小是 4096 个字节,你写入一个字节,或者写入 4096 个字节,都需要一次 I/O 操作,设置缓冲区,当写入的数据不足一个“块”大小时,都放入到缓冲区当中,等凑够了一个“块”的数据量,再调用一次 I/O 操作,这样达到减少 I/O 操作的目的。

01.Python中文件对象的缓冲行为

文件的缓冲一般分为“全缓冲”、“行缓冲”、“无缓冲”。

“全缓冲”就是我在上面说的,缓冲区有一定大小,数据凑齐了这个大小就进行一次系统调用;“行缓冲”是在某些终端设备中上使用,碰到换行符进行一次系统调用;“无缓冲”是在一些不希望进行缓冲的设备上,比如串口设备,我们就需要及时把数据发送到串口上去。

下面我们就来看一下,在 Python 中默认的文件对象缓冲行为是怎样的。

首先我们创建一个 test.txt 的文件,以“只写”的形式打开:

代码语言:javascript
复制
f = open('test.txt','w')

然后我们来观察一下文件中的内容(此时应该为空):

接下来我们向 test.txt 中写入一些内容:

代码语言:javascript
复制
f = open('test.txt','w')
f.write('abc')

我们再来看一下文件中的内容:

仍然没有输出,这就意味着 “abc” 并没有真实的写入到磁盘中,而是进入到了缓冲区,其实到这你可以探测一下缓冲区的大小,通常一个“块”的大小为 4096 个字节,你可以尝试写入来试验,直到 tail -f test.txt 有内容显示为止。

这就是普通文件默认的缓冲行为,缓冲区的大小是根据平台和自身的属性相关的。在某些时候,我们需要改变缓冲区的大小,该怎么做呢?

其实很好解决:在 open 函数中,有个 buffering 参数,可以让这个问题迎刃而解。

我们将 buffering 设置为大于 1 的整数 n(n 为缓冲区的大小),这就是“全缓冲”;将 buffering 设置为 1,这就是“行缓冲”;将 buffering 设置为 0,这就是“无缓冲”。

接下来我们就尝试一下:

代码语言:javascript
复制
f = open('test1.txt','w',buffering=1024)
f.write('*'*512)

我们用同样的“只读”方式创建 test1.txt,设定缓冲区大小为 1024,我们先写入 512 个 “*”,接下来看一下文件的内容:

接下来我们就凑齐 1024 个字节:

代码语言:javascript
复制
f = open('test1.txt','w',buffering=1024)
f.write('*'*512)
f.write('*'*511)
f.write('/')

此时文件的内容为:

这就全部输出出来了。

同理,对于“行缓冲”和“无缓冲”也是类似的操作,改变相应 buffering 的值即可,只是对于“行缓冲”,记得要写入换行符的时候才会在文件中显示出内容,感兴趣的可以尝试一下。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python空间 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档