linux系统编程-文件IO缓冲

1.什么是文件IO缓冲,为什么需要文件IO缓冲

  • 什么是文件IO缓冲
    顾名思义,用来缓存数据。read()和 write()系统调用在操作磁盘文件时不会直接发起磁盘访问,而是仅仅在用户空间缓冲区与内核缓冲区高速缓存之间复制数据。在后续某个时刻,内核会将其缓冲区中的数据写入磁盘(因此,可以说系统调用与磁盘操作并不同步。)
  • 为什么需要文件IO缓冲?
    A、更为快速,系统调用不需要等待磁盘操作。
    B、更为高效,减少了内核必须执行的磁盘传输次数。

2. 指定stdio缓冲区形式、刷新缓冲区

在这里插入图片描述

  • 如何指定stdio库缓冲区的形式?
int setvbuf(FILE *tream,char *buf, int mode, size_t size);

tream参数:表示一个文件流
buf 和 size 参数:则针对参数 stream 要使用的缓冲区,如果参数 buf 不为 NULL,那么其指向 size 大小的内存块以作为 stream 的缓冲区,若 buf 为 NULL,那么 stdio 库会为 stream 自动分配一个缓冲区。
mode参数
_IONBF :不对 I/O 进行缓冲。每个 stdio 库函数将立即调用 write()或者 read(),并且忽略 buf 和 size参数,也就是说文件流与内核缓冲区直接交换数据
_IOLBF :采用行缓冲 I/O。
_IOFBF :采用全缓冲 I/O。单次读、写数据(通过 read()或 write()系统调用)的大小与缓冲区相同。

  • 如何刷新缓冲区?

A、刷新stdio缓冲区中的数据到内核缓冲区、或内核缓冲区内容刷新到stdio缓冲区

int fflush(FILE *stream);

对于stdio的输出函数,例如fprintf(stdout,“abcde”);调用fflush(stdout)将stdio缓冲区中的数据强制刷新到内核缓冲区中(对应write调用写入到STDOUT_FILENO中),清空缓冲区会使得缓冲区中的所有数据立即显示到屏幕上。
对于stdio的输入函数,例如fgets(*str,n,stdin);调用fflush(stdin)将内核缓冲区的内容刷新到stdio缓冲区中,这将对其已缓冲的输入数据(对应read调用读取流文件STDIN_FILENO),清空缓冲区就是丢弃残留字符,让程序直接等待用户输入,避免引发奇怪的行为。

B、刷新内核缓冲区内容到磁盘

int fsync(int fd);  //与打开文件描述符 fd 相关的所有元数据都刷新到磁盘上
int sync(void); //更新所有内核缓冲区

3.同步IO:open时O_SYNC同步到磁盘缓冲区(注意是磁盘缓冲非内核缓冲)

当open时启用O_SYNC标志,write()调用会自动将数据刷新到磁盘缓冲区中:

fd = open(pathname, O_WRONLY | O_SYNC);

4.裸IO

open时指定O_DIRECT标志可以绕过缓存,直接将用户空间的数据传递到磁盘设备:

fd = open(pathname, O_WEONLY | O_DIRECT);

裸IO的限制条件:

A、用于传递数据的缓冲区,其内存边界必须对齐为块大小的整数倍。
B、数据传输的开始点,亦即文件和设备的偏移量,必须是块大小的整数倍。
C、待传递数据的长度必须是块大小的整数倍。

5.IO模式内核建议

内核可以根据 posix_fadvise()调用所提供的信息来优化对缓冲区高速缓存的使
用,(对文件进行预读处理),进而提高进程和整个系统的性能。

int posix_fadvise(int fd,off_t offset,off_t len,int advice);

参数offset 和 len 确定了建议所适用的文件区域
参数 advice 表示进程期望对文件采取的访问模式。具体为下列参数之一,列出部分:
POSIX_FADV_SEQUENTIAL
进程预计会从低偏移量到高偏移量顺序读取数据。在 Linux 中,该操作将文件预读窗口大小置为默认值的两倍。
POSIX_FADV_RANDOM
进程预计以随机顺序访问数据。在 Linux 中,该选项会禁用文件预读。
POSIX_FADV_WILLNEED
进程预计会在不久的将来访问指定的文件区域。内核将由 offset 和 len 指定区域的文件数据预先填充到缓冲区高速缓存中

6.库函数和系统调用混合使用进行文件IO

fileno函数可以将一个流文件转换为一个文件描述符:

int fileno(FILE *stream);

fdopen函数可以将文件描述符转换为流文件

FILE *fdopen(int fd,const char *mode);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值