高级文件I/O

分散-聚集I/O

分散-聚集I/O是一种进行输入和输出的方法。通过此方法,单一系统调用可以将缓冲区响亮写入单一数据流,或者将单一数据流读取到缓冲区向量。这个类型的IO之所以会有此名称,是因为数据会被分散至或聚集自特定的缓冲区向量。这种方式的输入和输出又成为向量I/O。相比较之下,标准读取和写入系统调用所提供的事线性I/O。

 

相比较与线性I/O的做法,分散-聚集I/O有几项优点:

更自然的I/O操作

    如果你的数据原本就是分段的,例如头文件中预定义的字段,向量I/O可对其进行直观的操作。

效率

    单次向量I/O操作可以取代多次线性I/O操作

性能

    比较与线性I/O的实现,向量I/O的实现除了可以减少系统调用的次数,还可以经内部的优化提供性能的改善。

原子性

    不同于多次线性I/O操作,一个进程可以执行单次向量I/O操作,不会与另一个进程的操作交叉在一起的风险。

 

readv()与writev()

POSIX 1003.1-2001定义了而且Linux实现了一堆采用分散-聚集I/O机制的系统调用。

 

readv()函数会把count个段从文件描述符fd读取进iov所描述的缓冲区:

 

writev()函数最多会把count个段从iov所描述的缓冲区写入至文件描述符fd.

 

尽管readv()和writev()函数的行为分别如同read()和write(),但是readv()和writev()会同时读取或写入多个缓冲区。

 

每个iovec结构可用来描述一个独立的缓冲区,这又成为一个段。一组段又称为向量。向量里的每个段描述了内存中应该读取或写入缓冲区的地址和长度。readv()函数在着手处理下一个缓冲区之前,通常会先把iov_len个字节全部写出。这两个函数总是会依次操作各个段,从iov[0]开始,然后是iov[1]等等,直到iov[count-1]

 

返回值

执行成功时,readv()和writev()会分别返回所读取或写入的字节数目。此数据应该是count个iov_len值的综合。发生错误时,系统调用会返回-1并且将errno设定成适当的值。这两个系统调用可以体验read()和write()系统调用可能遇到的任何错误,而且会在收到此类错误时设定相同的errno代码。此外,标准还定义了两种其他的错误状态。

 

首先,因为返回值的类型是ssize_t,如果count个iov_len值的综合大于SSIZE_MAX,则数据将不会被传送,此时会返回-1,并且将errno设定成EINVAL。

 

其次,POSIX规定count必须大于0以及小于或等于IOV_MAX,此项限制定义于<limits.h>。在Linux中,IOV_MAX目前是1024,。如果count为0,这两个系统调用会返回0。如果count大于IOV_MAX,则数据将不会被传送,此时会返回-1并且将errno设定成EINVAL。

 

writev范例程序

让我们来看一个简单的范例程序,它会写出了一个具有三个段的向量,每个段包含了一个长度不同的字符串。这个完成的程序足以示范writev()的用法,它虽然简单单具有实用性:

 

运行此程序会产生预期的结果

$./writev

wrote 148 bytes

读取此程序所写出的文件:

$cat buccaneer.txt

The term buccaneer comes from the word boucan.
A boucan is a wooden frame used for cooking meat.
Buccaneer is the West Indies name for a pirate.

 

readv()范例程序

现在让我们来看一个范例场合呢个徐,它会使用readv()系统调用来读取前一节利用向量I/O所产生的文本文件。同样,这时一个完整的程序。

 

运行前一节的程序后再运行此程序会产生如下的结果:

$./readv

0:The term buccaneer comes from the word boucan.
1:A boucan is a wooden frame used for cooking meat.
2:Buccaneer is the West Indies name for a pirate.

 

事实上,Linux内核内部所有I/O均采用向量的方式,尽管read()和write()被实现成向量I/O,但是向量中只有一个段。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值