当前位置: 首页 > news >正文

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('结束成功!')

相关文章:

  • 创建你的第一个Windows程序
  • Github 2024-06-10开源项目周报 Top15
  • 【区分】累次极限与二重极限
  • 机器学习中的神经网络重难点!纯干货(上篇)
  • 神经网络开发
  • 【Ardiuno】实验使用ESP32单片机实现高级web服务器暂时动态图表功能(图文)
  • 计算机组成原理之定点除法
  • Android 14 蓝牙主从模式切换
  • profile-3d-contrib,github三维立体图的使用
  • JDK17 你的下一个白月光
  • Docker部署Nginx下载站点服务
  • UML与设计模式
  • sourcemap
  • vue2 + echats macarons 选中样式的树状图
  • C++移动语义
  • 2017 年终总结 —— 在路上
  • Android 控件背景颜色处理
  • Angular Elements 及其运作原理
  • Angular 响应式表单 基础例子
  • angular2开源库收集
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • JavaScript DOM 10 - 滚动
  • PAT A1050
  • SpringCloud集成分布式事务LCN (一)
  • SQLServer之创建数据库快照
  • 多线程事务回滚
  • 搞机器学习要哪些技能
  • 判断客户端类型,Android,iOS,PC
  • 深度学习入门:10门免费线上课程推荐
  • 我与Jetbrains的这些年
  • 因为阿里,他们成了“杭漂”
  • 最近的计划
  • 2017年360最后一道编程题
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 函数计算新功能-----支持C#函数
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • # SpringBoot 如何让指定的Bean先加载
  • #android不同版本废弃api,新api。
  • #git 撤消对文件的更改
  • #pragma multi_compile #pragma shader_feature
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (k8s)Kubernetes 从0到1容器编排之旅
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (三)c52学习之旅-点亮LED灯
  • (十)c52学习之旅-定时器实验
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (四) 虚拟摄像头vivi体验
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (一)SvelteKit教程:hello world
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功