你真的理解IO流吗

IO常用在外设读写,比如磁盘文件、网络等等,是程序与设备数据交换的唯一方式。文章以文件IO为例,简要介绍IO原理,如何选择合适的IO操作。

IO流是什么

IO流是指面向字节流的IO,个人理解其实就是指带有缓冲的IO,也称标准IO,不带缓冲的IO称为系统IO。当使用不带缓冲的IO操作时,通常需要用户定义byte[]用于直接读写数据到设备中,每次读写的大小由用户定义;而使用带缓冲的IO操作或方法时,程序定义的byte[]则会先读写到IO库方法中实现的缓冲区,然后再读写到文件或磁盘中,其中经历了程序byte[] -> 标准库byte[] -> 内核cache(文件),看似多了一层数据(从标准缓冲区到程序缓冲)复制,但在实际使用过程中,标准IO有着独到的优势,基本大多数语言IO操作的实现都是通过调用标准IO或带有缓冲的IO库。

为什么要使用缓冲

无论是用户程序自定义byte[]系统调用读写,还是用户程序直接调用标准IO函数,所有的IO操作最终都需要通过OS内核完成。标准IO库函数中的操作也是通过系统调用把IO操作从用户空间传给内核,然后内核做相应IO操作。
那为什么需要使用byte[]字节缓冲呢?我们知道OS系统调用时需要陷入到内核态去完成,完成后再返回再继续执行用户态程序,这个操作过程的开销其实是非常昂贵的。用户程序中调用系统函数不像在用户态中那种入栈出栈调用(在同一块堆栈中完成),而是在内核中建立堆栈,这个堆栈与用户态并不是一个堆栈,不能通过传递内存地址相互访问,往往是通过数据复制或地址空间映射来完成访问,另外由于内核态的特权级和安全性,还需要涉及到传参的检验等等,所以在开发过程中尽量减小系统调用,减少开销。

那么使用缓冲的优点就是在系统调用时尽可能一次传递更多的数据,减小系统调用的次数。当然缓冲区的大小也不是越大越好,使用过程中也要考虑到硬件层面比如内存大小等,如果由用户程序自定义缓冲区,则需要综合平衡硬件、效率等各方面因素。而如果采用标准IO库函数,则减小了这方面的开发工作量,调用也方便,移植性较强,也不用关心各平台差异性。

下图可以用来说明标准IO与系统IO间的关系,其中stdio表示C标准IO库,图片来源于《Linux系统编程手册》。

io_cache01

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jKViWXuC-1596017903355)(…/image/cs/io_cache_01.jpg)]

IO性能对比

这里通过一段代码来比较两种IO在读操作上面的性能,有兴趣的同学也可以尝试比较写操作的性能,只是可能相对麻烦点,但在整个性能比较结果与以下demo不会有太多差异。

通过4个函数test_read_standard_iotest_read_standard_iotest_read_standard_io_8ktest_read_standard_io_line比较系统IO与标准IO、标准IO缓存大小选择、标准IO读取行函数使用等来比较两种IO的性能。代码清单如下:

#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<time.h>

// 读操作用的数组大小
#define READ_SIZE 4096

char C_BUF[8 * 1024];

// 系统IO读,用4096数组接收读数据
double test_read_system_io(char *filename);
// 标准IO读,用4096数组接收读数据
double test_read_standard_io(char *filename);
// 标准IO读,设置标准IO的缓冲大小为8K,用4096数组接收读数据
double test_read_standard_io_8k(char *filename);
// 标准IO读,按行读数据,标准IO缓冲大小为8K,用4096数组接收读数据
double test_read_standard_io_line(char *filename);

int main(int argc, char *argv[]) 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值