Linux内核入门(三)——fread、read、fgets、fgetc函数

时间:2024-10-23 09:14:20

Linux内核入门(三)——read、fread、fgets、fgetc函数

  • 前言
  • 缓存哪里来?
  • 全缓存,行缓存,无缓存区别
  • 常见行缓存,全缓存,无缓存函数有哪些
  • read、fread、fgets、fgetc四组读写函数效率比较

前言

上一篇博客讲到,使用open、close、read、write等函数,处理上述IO函数外,我们还可以使用c函数库提供的标准IO读写函数对文件进行操作。
下图展示了,标准IO和文件IO之间的区别,简单来说就是,文件IO是由系统调用提供的,可以直接对文件读写的函数。而标准IO则经过一个叫“c函数库”的中间商,实现对文件的读写。

标准IO里面的函数众多,可分为三种:全缓存,行缓存,无缓存
哪来的缓存这个东西呢?

缓存哪里来?

在使用标准IO函数的时候,因为有C函数库这个中间商存在,所以会多出来一个库缓存,干嘛用的呢,就是,用户想要和内核交换数据,不是直接交换了,数据得先在这个“库缓存”里待一会,待到什么时候呢

全缓存,行缓存,无缓存区别

很简单
行缓存是遇到‘\n’(换行符),或者行缓存被写满,就把缓存里的东西拿出来
全缓存就是写满缓存后,再把缓存里的东西拿出来
无缓存,就是根本不经过缓存。

除此之外:遇到:fclose函数,fflush函数,缓存里的东西也会被赶出来。
在这里插入图片描述

常见行缓存,全缓存,无缓存函数有哪些

  1. 行缓存:
    读:fgets,printf,fprintf 等
    写:fputs,scanf
  2. 全缓存:
    读:fread
    写:fwrite
  3. 无缓存:
    读:read
    写:write

这里有个另类:fgetc和fputc(单个字符的读写),这两函数有缓存,但不是行缓存,也不是全缓存

read、fread、fgets、fgetc四组读写函数效率比较

我们有这么多组读写函数,那哪个比较好呢,这里做个测试:
写一个拷贝函数,分别使用上面四组读写函数拷贝一个同样大小的文件,运行查看他们需要用到的时间:
先来看上一篇博客用到的读写函数:read,write
在这里插入图片描述
因为是无缓存函数,所以没在库缓存中多做停留,直接往内核里去了,时间都耗在sys这里,总时间real为0.169s

再看下一位选手:fgetc,fputc
在这里插入图片描述
稍微快了一点,但还是不够快,因为是一个字符一个字符读取,写入的,又因为用到了库缓存,所以在用户空间的时间user长了一点,总时间real为:0.162s

再看跟上面一位长得差不多的:fgets,fputs
fgetc是一个字符一个字符读取,fgets是成串成串地读取,读多少取决于你给fgets的参数“size”是多少。
在这里插入图片描述
哇塞!好快,只用了0.026s
成串地读写,行缓存函数占据优势

再看最后一位:fread,fwrite
这是全缓存函数,这对函数能否创造奇迹,超越上一位呢?
在这里插入图片描述
用时:0.013s!!!

fread,fwrite使用全缓存技术,赢得了本次地冠军!