• 6.2 文件的缓存位置


    1. 文件的缓冲

    1.1 缓冲说明
    将文件内容写入到硬件设备时, 则需要进行系统调用, 
    这类I/O操作的耗时很长, 为了减少I/O操作的次数, 文件通常使用缓冲区.
    当需要写入的字节数不足一个块时, 将数据放入缓冲区, 当数据凑够一个块的大小后才进行系统调用(即I/O操作).
    
    系统调用: 向操作系统申请一个服务, 操作系统响应后, 帮助调用硬件的驱动程序, 这种操作称为I/O操作.
    
    1.2 文件的缓冲行为:
    全缓冲: 只有当数据凑够一个块时, 才进行系统调用(即I/O操作).
    
    行缓冲: 碰到一个'换行符', 就进行一次系统调(多用于tty设备, 也就是终端设备, 如shell).
    
    无缓冲: 不进行缓冲, 需要及时的将数据发送到接口(比如串口设备).
    
    1.3 补充知识
    机械硬盘的盘面可以分为很多磁道, 可以将磁道划分为个扇区.
    
    扇区: 是磁盘的最小组成单元, 是磁盘的读写基本单位, 传统一个扇区为512字节.
    硬盘公司大概在2010年左右, 开始从传统的512字节扇区大小磁盘迁移到更高效的4096字节(目前还是很少).
    
    由于扇区的数量比较小且数目众多, 在寻址时比较困难, 
    所以操作系统就将相邻的扇区组合在一起, 形成一个块, 再对块进行整体的操作.
    
    : 是操作系统与磁盘之间交流的最小单位, 它是一个虚拟的概念. 
    操作系统忽略对底层物理存储结构的设计, 虚拟出来磁盘块的概念, 在系统中认为块是最小的单位.
    它的所以大小可以通过操作系统设置, 一个块通常是4K(4096字节).
    对应扇区为512字节的硬盘来说, 1个块是由连续的8个扇区组成.
    对应扇区为4096字节的硬盘来说, 1个块是由1个扇区组成.
    
    固态硬盘与内存使用是闪存芯片, 没有扇区一说而是称为页, 
    固态硬盘一个页是8KB甚至16KB的, 内存一个页是64k.
    

    2. buffering 参数

    Python的文件对象的默认的缓冲行为全缓冲, 当凑够一个块的数据才进行系统调用.
    缓冲区的大小是根据平台和块设备自身的属性相关, 可以通过open函数buffering参数设置缓冲大小.
    
    buffering参数设置缓冲模式以及缓冲区大小.
    buffering = n, n > 1, 设定缓冲模式为全缓冲, 缓冲区大小为n个字节.
    buffering = 1, 设定缓冲模式为行缓冲, 遇到换行符'\n'时进行系统调用, 不支持二进制格式.
    buffering = 0, 此为无缓冲你模式, 只要有数据, 就直接进行系统调用.
    

    3. 交互模式演示

    * 以脚本方式运行, 在文件句柄关闭时会将缓存区的数据刷入硬盘中, 不好看测试效果.
    
    import io
    
    # 查看默认缓冲区大小
    print(io.DEFAULT_BUFFER_SIZE)  # 8192
    
    # 创建文件对象, b模式方便计算写入的字节.
    f = open('a.txt', 'wb')
    
    # 写入1000个字节的数据.
    f.write(b'1' * 1000)  # 这个时候在打开a.txt文件, 是空白的.
    input('回车继续写!')
    
    # 在写入7190个字节的数据, 现在共有8190个字节.
    f.write(b'1' * 7190)  # 这个时候在打开a.txt文件, 是空白的.
    input('回车继续写!')
    
    # 在写入2个字节的数据, 现在共有8192个字节, 这个时候缓存区满了可它没有立刻写进去...
    f.write(b'1' * 2)
    input('回车继续写!')
    
    # 在写一个字节, 缓存的数据写入到硬盘中. 查看文件字符个数为8192个字节.
    f.write(b'1' * 1)
    input('回车结束程序!')  # 这个时候文件字符个数为8193个字节.
    
    
    # 设置全缓冲区的大小为2048.
    f2 = open('b.txt', 'wb', buffering=2048)
    f2.write(b'+' * 1024)
    input('回车继续写!')
    f2.write(b'+' * 1024)
    input('回车继续写!')
    # 在写一个字符, 缓存的数据写入到硬盘中.
    f2.write(b'-' * 1)
    input('结束程序!')
    
    
    # 设置行缓冲, buffering为1.
    f3 = open('c.txt', 'w', encoding='utf8', buffering=1)
    input('回车继续写!')
    f3.write('abc')
    input('回车继续写!')
    f3.write('123')
    input('回车继续写!')
    # 这个时候, 缓存的数据写入到硬盘中.
    f3.write('\n')
    input('结束程序!')
    
    
    # 无缓冲, buffering为0.
    f4 = open('d.txt', 'wb', buffering=0)
    f4.write(b'a')
    input('回车继续写!')
    f4.write(b'b')
    input('结束成功!')
    
    
  • 相关阅读:
    BiLSTM算法(一)
    零零信安-D&D数据泄露报警日报【第38期】
    Spring 如何解决循环依赖
    简洁高性能读服务架构
    清除linux内存buff/cache
    [附源码]Python计算机毕业设计Django环境保护宣传网站
    Python:实现circle sort圆形排序算法(附完整源码)
    小土堆-pytorch-神经网络-搭建小实战和Sequential 09_笔记
    并发编程——LockSupport工具和Condition接口
    实验9 静态路由配置
  • 原文地址:https://blog.csdn.net/qq_46137324/article/details/139667809