1. 文件的缓冲
1.1 缓冲说明
将文件内容写入到硬件设备时 , 则需要进行系统调用 ,
这类I / O操作的耗时很长 , 为了减少I / O操作的次数 , 文件通常使用缓冲区 .
当需要写入的字节数不足一个块时 , 将数据放入缓冲区 , 当数据凑够一个块的大小后才进行系统调用 ( 即I / O操作 ) .
系统调用 : 向操作系统申请一个服务 , 操作系统响应后 , 帮助调用硬件的驱动程序 , 这种操作称为I / O操作 .
1.2 文件的缓冲行为:
全缓冲 : 只有当数据凑够一个块时 , 才进行系统调用 ( 即I / O操作 ) .
行缓冲 : 碰到一个 '换行符' 时 , 就进行一次系统调 ( 多用于tty设备 , 也就是终端设备 , 如shell ) .
无缓冲 : 不进行缓冲 , 需要及时的将数据发送到接口 ( 比如串口设备 ) .
1.3 补充知识
机械硬盘的盘面可以分为很多磁道 , 可以将磁道划分为个扇区 .
扇区 : 是磁盘的最小组成单元 , 是磁盘的读写基本单位 , 传统一个扇区为 512 字节 .
硬盘公司大概在 2010 年左右 , 开始从传统的 512 字节扇区大小磁盘迁移到更高效的 4096 字节 ( 目前还是很少 ) .
由于扇区的数量比较小且数目众多 , 在寻址时比较困难 ,
所以操作系统就将相邻的扇区组合在一起 , 形成一个块 , 再对块进行整体的操作 .
块 : 是操作系统与磁盘之间交流的最小单位 , 它是一个虚拟的概念 .
操作系统忽略对底层物理存储结构的设计 , 虚拟出来磁盘块的概念 , 在系统中认为块是最小的单位 .
它的所以大小可以通过操作系统设置 , 一个块通常是 4 K ( 4096 字节 ) .
对应扇区为 512 字节的硬盘来说 , 1 个块是由连续的 8 个扇区组成 .
对应扇区为 4096 字节的硬盘来说 , 1 个块是由 1 个扇区组成 .
固态硬盘与内存使用是闪存芯片 , 没有扇区一说而是称为页 ,
固态硬盘一个页是 8 KB甚至 16 KB的 , 内存一个页是 64 k .
2. buffering 参数
Python的文件对象的默认的缓冲行为全缓冲 , 当凑够一个块的数据才进行系统调用 .
缓冲区的大小是根据平台和块设备自身的属性相关 , 可以通过open函数buffering参数设置缓冲大小 .
buffering参数设置缓冲模式以及缓冲区大小 .
buffering = n , n > 1 , 设定缓冲模式为全缓冲 , 缓冲区大小为n个字节 .
buffering = 1 , 设定缓冲模式为行缓冲 , 遇到换行符 '\n' 时进行系统调用 , 不支持二进制格式 .
buffering = 0 , 此为无缓冲你模式 , 只要有数据 , 就直接进行系统调用 .
3. 交互模式演示
* 以脚本方式运行 , 在文件句柄关闭时会将缓存区的数据刷入硬盘中 , 不好看测试效果 .
import io
print ( io. DEFAULT_BUFFER_SIZE)
f = open ( 'a.txt' , 'wb' )
f. write( b'1' * 1000 )
input ( '回车继续写!' )
f. write( b'1' * 7190 )
input ( '回车继续写!' )
f. write( b'1' * 2 )
input ( '回车继续写!' )
f. write( b'1' * 1 )
input ( '回车结束程序!' )
f2 = open ( 'b.txt' , 'wb' , buffering= 2048 )
f2. write( b'+' * 1024 )
input ( '回车继续写!' )
f2. write( b'+' * 1024 )
input ( '回车继续写!' )
f2. write( b'-' * 1 )
input ( '结束程序!' )
f3 = open ( 'c.txt' , 'w' , encoding= 'utf8' , buffering= 1 )
input ( '回车继续写!' )
f3. write( 'abc' )
input ( '回车继续写!' )
f3. write( '123' )
input ( '回车继续写!' )
f3. write( '\n' )
input ( '结束程序!' )
f4 = open ( 'd.txt' , 'wb' , buffering= 0 )
f4. write( b'a' )
input ( '回车继续写!' )
f4. write( b'b' )
input ( '结束成功!' )