20.4-缓冲区

作者: BeautifulSoulpy | 来源:发表于2019-09-25 19:58 被阅读0次

我们一路奋斗,不是为了改变世界,而是为了,不让世界改变我们!

I/O 操作很耗时,为了提高效率,我们就要减少 I/O 操作的次数,我们使用的手段就是为文件设置一个缓冲区。

先进先出;缓冲区取自 操作系统原理;

文件系统、网络系统属于操作系统,Python使用的还是操作系统的能力;不学习操作系统还是不会编程;

缓冲分类

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

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

buffering 是一个可选的整数,用于设置缓冲策略。

传递0以切换缓冲关闭(仅允许在二进制模式下)。
传递1选择 行缓冲(仅在文本模式下可用)。
传递大于1的整数以指示固定大小的块缓冲区的大小(以字节为单位)。

如果没有给出 buffering 参数,则默认缓冲策略的工作方式如下:
二进制文件以固定大小的块进行缓冲;使用启发式方法选择缓冲区的大小,尝试确定底层设备的“块大小”或使用 io.DEFAULT_BUFFER_SIZE。在许多系统上,缓冲区的长度通常为4096或8192字节。

Python 中默认的文件对象缓冲行为
缓冲区为一个内存空间,一般来说是一个FIFO队列,到缓冲区满了或者达到阙值,数据才会flush到磁盘;

先看二进制模式:

import io
f = open('test4','w+b')
print(io.DEFAULT_BUFFER_SIZE)   |   8192
f.write(b'magedu')     |    6
f.write(b'xyz')        |    3
f.seek(0)              |    0
f.read()               |    b'mageduxyz'
f.seek(0)        |  0
f.write(b'xyz')  |  3
f.read()         |  b'eduxyz'        # 完全覆盖;

只要seek()一次,就会将缓冲强行写入一次;
flush()将缓冲区数据写入磁盘close()关闭前会调用flush()
io.DEFAULT_BUFFER_SIZE缺省缓冲区大小、字节;

f = open('test5','wb+')
print(io.DEFAULT_BUFFER_SIZE)
f.write("magedu.com".encode())
f.seek(0)
f.read()   |   b'magedu.com'
f.write("www.magedu.com".encode())  
f.flush()
f.read()    |    magedu.comwww.magedu.com

文件系统的批处理

缓冲区大小是有用的;
f = open('test5','w+b',4)
print(io.DEFAULT_BUFFER_SIZE)
f.write(b'mag')
f.write(b'x')
f.write(b'x')
f.read()
---------------
magx


f = open('test5','rb+',1)  # 缓冲区大小为1,不是文本模式;


行缓冲模式  bufferring = 1(了解就行,很少用)
f = open('test6','r+',1)
print(io.DEFAULT_BUFFER_SIZE)   # 8192
f.write('mag'*10)
f.write('\n')
f.seek(0)
f.read()
-------------------
'magmagmagmagmagmagmagmagmagmag\n'


文本模式下,10并不代表缓冲区大小,实际 bufferring = 缺省值8192(了解就行,很少用)
f = open('test6','r+',10)

一般来说,只需要记住:

  1. 文本模式,一般都用默认缓冲区大小
  2. 二进制模式,是一个个字节的操作,可以指定buffer的大小
  3. 一般来说,默认缓冲区大小是个比较好的选择,除非明确知道,否则不调整它
  4. 一般编程中,明确知道需要写磁盘了,都会手动调用一次flush,而不是等到自动flush或者close的时候

相关文章

  • 20.4-缓冲区

    我们一路奋斗,不是为了改变世界,而是为了,不让世界改变我们! I/O 操作很耗时,为了提高效率,我们就要减少 I/...

  • OpenGL模板缓冲区与模板测试(转)

    OpenGL模板缓冲区与模板测试 帧缓冲区有许多缓冲区构成,这些缓冲区大致分为: 颜色缓冲区:用于绘图的缓冲区,它...

  • OutputStream 输出流 写

    // 带写缓冲区,缓冲区大小10,缓冲区内存中, 1,2,3,4把他们都放到缓冲区--缓冲区满是才写到文件 // ...

  • Socket缓冲区以及阻塞模式

    socket缓冲区每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区。write()/sen...

  • 循环缓冲区

    参考 圆形缓冲区(循环buffer)实现35.Linux-分析并制作环形缓冲区 环形缓冲区构成一般的,圆形缓冲区需...

  • 11.18

    Java 中,直接缓冲区与非直接缓冲器有什么区别?非直接缓冲区:通过allocate()分配缓冲区,将缓冲区建立在...

  • [Java NIO] 缓冲区

    一.缓冲区 2.1 缓冲区 1.概念 缓冲区以及缓冲区如何工作,是所有IO的基础。 所谓输入/输出,无非是把数据移...

  • OpenGL ES 3.0(六)缓冲区对象、PBO、FBO

    缓冲区对象 创建: 绑定: 缓冲区对象的绑定点有: 删除: 填充缓冲区: 在使用 glBufferData 之前,...

  • mmap和sendfile

    mmap mmap主要实现方式是将读缓冲区的地址和用户缓冲区的地址进行映射,内核缓冲区和应用缓冲区共享,从而减少了...

  • WEBGL编程指南之缓冲区的使用

    1. 创建缓冲区的步骤 创建缓冲区对象(gl.createBuffer()) 绑定缓冲区对象(gl.bindBuf...

网友评论

    本文标题:20.4-缓冲区

    本文链接:https://www.haomeiwen.com/subject/skqwuctx.html