1.标准I/O缓冲区

要理解标准I/O,就要先知道文件I/O的业务逻辑。

下面图示为文件I/O

如执行下面的代码:

write(fd, buf2, sizeof(buf2));

图中

buf:就是buf2。

缓冲区:是文件系统的页缓存。

当执行写操作时,buf中的数据会被复制到内核空间的页缓冲区,如果使用的是同步写,那么数据会从页缓冲写到磁盘,如果使用的是延迟写,那么数据不会立即写入磁盘,只有当页缓冲区满了,或者页缓冲区被其他I/O使用时,才会写入磁盘。

当执行读操作时,磁盘数据先被复制到页缓冲,进程再从页缓冲中取数据,当页缓冲空间大小大于用户要求读取的数据量时,文件系统会假设用户紧接着会读取后面连续的数据,所以会将随后的数据预先载入页缓冲,这样用户下次读时,就可以直接从页缓冲中读取。

标准I/O的不足就是 buf 的大小不一定等于页缓冲区的大小,当 buf 的大小小于页缓冲区的大小时,一次写后页缓冲区并没有被填满,便进行了一次磁盘访问。文件I/O对此进行了改进。

2.文件I/O缓冲区

文件I/O的图示如下:

我们知道文件I/O是对文件流对象进行操作的,FILE 中重要的数据结构就是:文件描述符、指向缓冲区的指针。

文件I/O多了一个缓冲区,该缓冲区由 malloc分配,在用户空间,并且它的大小和内核页缓冲区的大小匹配。

当执行全缓冲的写操作时,buf中的数据先复制到流缓冲区中,当流缓冲区填充满后,再复制到内核页缓冲区,然后访问磁盘,写入数据。

当执行读操作时,第一次读操作:数据从磁盘复制到页缓冲,再从页缓冲复制到流缓冲,进程从流缓冲中复制需要的数据,由于每个流都有自己的流缓冲,那么当页缓冲中数据被刷掉后,进程不需要调用read函数,而只需要读自己的流缓冲区中预先读取的数据。

文件I/O提高速率的方法就是:尽量让流缓冲区填满后,再将数据传送给内核的页缓冲区,这样每次访问磁盘,都可以最大效率的传送数据。

3.实验证明效率

用三种不同的函数,完成读文件后写到标准输出的工作。

对文件 I/O,标准 I/O 的缓冲的理解的更多相关文章

  1. 文件IO和标准IO的区别【转】

    一.先来了解下什么是文件I/O和标准I/O: 文件I/O:文件I/O称之为不带缓存的IO(unbuffered I/O).不带缓存指的是每个read,write都调用内核中的一个系统调用.也就是一般所 ...

  2. 文件IO与标准IO的区别

    文件IO与标准IO的区别 文件I/O就是操作系统封装了一系列函数接口供应用程序使用,通过这些接口可以实现对文件的读写操作,文件I/O是采用系统直接调用的方式,因此当使用这些接口对文件进行操作时,就会立 ...

  3. 文件IO和标准IO

    2015.2.26 星期四,阴天 今天的内容主要是文件IO man 手册的分册: man -f open 查看那些分册中有openman 1 -- 普通的命令程序man 2 -- 系统调用man 3 ...

  4. [一]FileDescriptor文件描述符 标准输入输出错误 文件描述符

    文件描述符   当应用程序请求打开或者操作文件时,操作系统为应用程序设置一张文件列表,具体的实现形式此处不深入说明 操作系统会提供给你一个非负整数,作为一个索引号,它的作用就像地址或者说指针或者说偏移 ...

  5. C基础 大文件读取通过标准库

    引言 - 问题的构建 C大部分读取文件的时候采用fgetc, 最近在使用过程中发现性能不是很理想.都懂得fgetc每次只能读取一个字符, IO操作太频繁. 所以性能低. 本文希望通过标准库函数frea ...

  6. linux文件io与标准io

    文件IO实际是API,Linux对文件操作主要流程为:打开(open),操作(write.read.lseek),关闭(close). 1.打开文件函数open(): 涉及的头文件:  #includ ...

  7. Linux中从oracle官网下载jdk文件不是标准的gzip格式文件问题

    首先你要知道,在linux系统中,文件类型跟后缀名无关,后缀名只是为了方便识别,所以你下载的压缩包可能是tar.gz格式的,也有可能是tar.bz2或tar.xz格式,因为可能别人压缩之后不小心改错了 ...

  8. java IO流文件拷贝文件(字节流标准写法)

    public static void copyFile(String srcPath, String destPath) { FileInputStream fis = null; FileOutpu ...

  9. 标准输入输出 stdio 流缓冲

    **From : http://www.pixelbeat.org/programming/stdio_buffering/** 我发现找出标准流用的是什么缓冲是一件困难的事. 例如下面这个使用uni ...

随机推荐

  1. centos yum 安装jdk后配置JAVA_HOME

    centos6.4 yum 安装jdk和JAVA_HOME的设置 2014-06-17 16:13 1176人阅读 评论(0) 收藏 举报  分类: linux(3)  版权声明:本文为博主原创文章, ...

  2. 简单封装的web里面的tab点击和swipe滑动的小插件

    简单封装的一个web的手势,tab和swipe,里面的具体数值都是自定义上去的,没有实际的标准,可以自行去修改都行 前两个是详解,js插件在最后一部分代码 ``` //封装web的tab步骤详解 &l ...

  3. DOM 事件冒泡

    1.什么是事件冒泡? 事件冒泡就是从具体到不具体, 例如:当你给了一个button按钮一个点击事件,再给他的父级相同的事件,就会按照,button,body,document,window,继续向上冒 ...

  4. 切图让我进步!关于white-space属性的组合拳

    菜鸟一枚,没有大神的风骚,只有一点在练习中的心得,今天获得的知识是关于white-space属性.overflow属性还有text-overflow属性的组合使用,废话不多说浪费时间,进入今天的正题! ...

  5. php-fpm如何优化进程数

    参考链接: php-fpm进程数优化

  6. selenium profile remotedriver

    使用 FirefoxProfile FirefoxProfilefp = new FirefoxProfile(); // set something on the profile... Desire ...

  7. Vim-命令合集

    命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filename 打开vim ...

  8. github设置添加SSH(转载自:破男孩)

    注:本文来源于 破男孩 博客(http://www.cnblogs.com/ayseeing/p/3572582.html)能切实解决问题. 很多朋友在用github管理项目的时候,都是直接使用htt ...

  9. Cydia Tweak--Cydia Substrate

    http://www.jianshu.com/p/8982e9670fc6 Cydia Substrate.MobileHooker MSHookMessageEx MSHookFunction Mo ...

  10. NOIP2018学军中学游记(11.09~11.11)

    前言 这篇博客记录的是我在\(NOIP2018\)提高组比赛中的经历. 这一次的\(NOIP\)是在学军中学举办的, 莫名感到一阵慌张. 但愿能有一个好成绩,不然就要\(AFO\)了... ... 说 ...