基于Linux平台的高级IO扩展函数

摘要:
由于read、readv、write和writev函数不能同时满足所需的数据,因此需要多次调用它们,直到达到所需的字节数或发生错误。
由于read、readv、write和writev函数一次读或写有时并不能满足所要求的数据,因此需要多次调用直到要求的字节数或者出错。针对这4个系统调用,编写了对应的xxxn版本,实现如下
  1基于Linux平台的高级IO扩展函数第1张/**********************************************************************************************************
  2基于Linux平台的高级IO扩展函数第2张 In the following four functions,the optional parameter tran indicate the number of bytes read or written,or -1 if an error occurred.
  3基于Linux平台的高级IO扩展函数第2张 On success,return true indicate all data had been read or written successfully,otherwise in other cases,return false indicate error or partial success.
  4基于Linux平台的高级IO扩展函数第4张**********************************************************************************************************/

  5基于Linux平台的高级IO扩展函数第5张 
  6基于Linux平台的高级IO扩展函数第1张bool readn(int fd,void* buf,size_t cnt,ssize_t* tran/*=NULL*/)
  7基于Linux平台的高级IO扩展函数第1张{
  8基于Linux平台的高级IO扩展函数第2张    size_t left = cnt;
  9基于Linux平台的高级IO扩展函数第2张    ssize_t ret;
 10基于Linux平台的高级IO扩展函数第2张    char* ptr = (char*)buf;
 11基于Linux平台的高级IO扩展函数第2张    
 12基于Linux平台的高级IO扩展函数第12张    while(left > 0){
 13基于Linux平台的高级IO扩展函数第2张        ret = read(fd,buf,left);
 14基于Linux平台的高级IO扩展函数第12张        if(ret > 0){
 15基于Linux平台的高级IO扩展函数第2张            left -= ret;
 16基于Linux平台的高级IO扩展函数第2张            ptr += ret;
 17基于Linux平台的高级IO扩展函数第17张        }
else if(0==ret || left != cnt)
 18基于Linux平台的高级IO扩展函数第2张            break;
 19基于Linux平台的高级IO扩展函数第12张        else{
 20基于Linux平台的高级IO扩展函数第2张            if(tran) *tran = -1;
 21基于Linux平台的高级IO扩展函数第2张            return false;        
 22基于Linux平台的高级IO扩展函数第17张        }

 23基于Linux平台的高级IO扩展函数第17张    }

 24基于Linux平台的高级IO扩展函数第2张    if(tran) *tran = cnt-left;
 25基于Linux平台的高级IO扩展函数第2张    return 0==left;
 26基于Linux平台的高级IO扩展函数第4张}

 27基于Linux平台的高级IO扩展函数第5张
 28基于Linux平台的高级IO扩展函数第1张bool writen(int fd,const void* buf,size_t cnt,ssize_t* tran/*=NULL*/)
 29基于Linux平台的高级IO扩展函数第1张{
 30基于Linux平台的高级IO扩展函数第2张    size_t left = cnt;
 31基于Linux平台的高级IO扩展函数第2张    ssize_t ret;
 32基于Linux平台的高级IO扩展函数第2张    char* ptr = (char*)buf;
 33基于Linux平台的高级IO扩展函数第2张
 34基于Linux平台的高级IO扩展函数第12张    while(left > 0){
 35基于Linux平台的高级IO扩展函数第2张        ret = write(fd,buf,left);
 36基于Linux平台的高级IO扩展函数第12张        if(ret > 0){
 37基于Linux平台的高级IO扩展函数第2张            left -= ret;
 38基于Linux平台的高级IO扩展函数第2张            ptr += ret;
 39基于Linux平台的高级IO扩展函数第17张        }
else if(0==ret || left != cnt)
 40基于Linux平台的高级IO扩展函数第2张            break;
 41基于Linux平台的高级IO扩展函数第2张        else
 42基于Linux平台的高级IO扩展函数第2张            if(tran) *tran = -1;
 43基于Linux平台的高级IO扩展函数第2张            return false;        
 44基于Linux平台的高级IO扩展函数第17张    }

 45基于Linux平台的高级IO扩展函数第2张    if(tran) *tran = cnt-left;
 46基于Linux平台的高级IO扩展函数第2张    return 0==left;
 47基于Linux平台的高级IO扩展函数第4张}

 48基于Linux平台的高级IO扩展函数第5张
 49基于Linux平台的高级IO扩展函数第5张static int get_iov_tran_index(const struct iovec* iov,int iovcnt,size_t trans,size_t& tran)
 50基于Linux平台的高级IO扩展函数第1张{
 51基于Linux平台的高级IO扩展函数第2张    size_t cnt = 0;  int i;
 52基于Linux平台的高级IO扩展函数第2张
 53基于Linux平台的高级IO扩展函数第12张    for(i=0;i < iovcnt;++i){
 54基于Linux平台的高级IO扩展函数第2张        cnt += iov[i].iov_len;
 55基于Linux平台的高级IO扩展函数第12张        if(trans < cnt){
 56基于Linux平台的高级IO扩展函数第2张            tran = iov[i].iov_len - (cnt - tran);
 57基于Linux平台的高级IO扩展函数第2张            break;
 58基于Linux平台的高级IO扩展函数第17张        }

 59基于Linux平台的高级IO扩展函数第17张    }

 60基于Linux平台的高级IO扩展函数第2张    return i;
 61基于Linux平台的高级IO扩展函数第4张}

 62基于Linux平台的高级IO扩展函数第5张
 63基于Linux平台的高级IO扩展函数第1张bool readvn(int fd,const struct iovec* iov,int iovcnt,ssize_t* tran/*=NULL*/)
 64基于Linux平台的高级IO扩展函数第1张{
 65基于Linux平台的高级IO扩展函数第12张    if(iovcnt > IOV_MAX){
 66基于Linux平台的高级IO扩展函数第2张        if(tran) *tran = -1;
 67基于Linux平台的高级IO扩展函数第2张        errno = EINVAL;    
 68基于Linux平台的高级IO扩展函数第2张        return false;
 69基于Linux平台的高级IO扩展函数第17张    }

 70基于Linux平台的高级IO扩展函数第2张    size_t all_cnt = 0,all_tran = 0,one_tran;
 71基于Linux平台的高级IO扩展函数第2张    ssize_t ret;
 72基于Linux平台的高级IO扩展函数第2张
 73基于Linux平台的高级IO扩展函数第2张    struct iovec _iov[IOV_MAX];
 74基于Linux平台的高级IO扩展函数第2张    int i;
 75基于Linux平台的高级IO扩展函数第12张    for(i=0;i < iovcnt;++i)
 76基于Linux平台的高级IO扩展函数第2张        _iov[i] = iov[i];    
 77基于Linux平台的高级IO扩展函数第2张        all_cnt += iov[i].iov_len;
 78基于Linux平台的高级IO扩展函数第17张    }

 79基于Linux平台的高级IO扩展函数第2张
 80基于Linux平台的高级IO扩展函数第2张    i = 0;
 81基于Linux平台的高级IO扩展函数第12张    do{
 82基于Linux平台的高级IO扩展函数第2张        ret = readv(fd,&_iov[i],iovcnt-i);
 83基于Linux平台的高级IO扩展函数第12张        if(ret > 0){
 84基于Linux平台的高级IO扩展函数第2张            all_tran += ret;    
 85基于Linux平台的高级IO扩展函数第2张            if(all_tran==all_cnt)
 86基于Linux平台的高级IO扩展函数第2张                break;
 87基于Linux平台的高级IO扩展函数第2张
 88基于Linux平台的高级IO扩展函数第2张            i = get_iov_tran_index(iov,iovcnt,all_tran,one_tran);
 89基于Linux平台的高级IO扩展函数第2张            assert(i < iovcnt);
 90基于Linux平台的高级IO扩展函数第2张            _iov[i].iov_base = iov[i].iov_base + one_tran;                
 91基于Linux平台的高级IO扩展函数第2张            _iov[i].iov_len  = iov[i].iov_len - one_tran;
 92基于Linux平台的高级IO扩展函数第2张
 93基于Linux平台的高级IO扩展函数第17张        }
else if(0==ret)
 94基于Linux平台的高级IO扩展函数第2张            break;
 95基于Linux平台的高级IO扩展函数第12张        else{
 96基于Linux平台的高级IO扩展函数第2张            if(tran) *tran = -1;
 97基于Linux平台的高级IO扩展函数第2张            return false;
 98基于Linux平台的高级IO扩展函数第17张        }

 99基于Linux平台的高级IO扩展函数第17张    }
while(all_tran < all_cnt);
100基于Linux平台的高级IO扩展函数第2张
101基于Linux平台的高级IO扩展函数第2张    if(tran) *tran = all_tran;
102基于Linux平台的高级IO扩展函数第2张    return all_tran==all_cnt;
103基于Linux平台的高级IO扩展函数第4张}

104基于Linux平台的高级IO扩展函数第5张
105基于Linux平台的高级IO扩展函数第1张bool writevn(int fd,const struct iovec* iov,int iovcnt,ssize_t* tran/*=NULL*/)
106基于Linux平台的高级IO扩展函数第1张{
107基于Linux平台的高级IO扩展函数第12张    if(iovcnt > IOV_MAX){
108基于Linux平台的高级IO扩展函数第2张        if(tran) *tran = -1;
109基于Linux平台的高级IO扩展函数第2张        errno = EINVAL;    
110基于Linux平台的高级IO扩展函数第2张        return false;
111基于Linux平台的高级IO扩展函数第17张    }

112基于Linux平台的高级IO扩展函数第2张    size_t all_cnt = 0,all_tran = 0,one_tran;
113基于Linux平台的高级IO扩展函数第2张    ssize_t ret;
114基于Linux平台的高级IO扩展函数第2张
115基于Linux平台的高级IO扩展函数第2张    struct iovec _iov[IOV_MAX];
116基于Linux平台的高级IO扩展函数第2张    int i;
117基于Linux平台的高级IO扩展函数第12张    for(i=0;i < iovcnt;++i)
118基于Linux平台的高级IO扩展函数第2张        _iov[i] = iov[i];    
119基于Linux平台的高级IO扩展函数第2张        all_cnt += iov[i].iov_len;
120基于Linux平台的高级IO扩展函数第17张    }

121基于Linux平台的高级IO扩展函数第2张
122基于Linux平台的高级IO扩展函数第2张    i = 0;
123基于Linux平台的高级IO扩展函数第12张    do{
124基于Linux平台的高级IO扩展函数第2张        ret = writev(fd,&_iov[i],iovcnt-i);
125基于Linux平台的高级IO扩展函数第12张        if(ret > 0){
126基于Linux平台的高级IO扩展函数第2张            all_tran += ret;    
127基于Linux平台的高级IO扩展函数第2张            if(all_tran==all_cnt)
128基于Linux平台的高级IO扩展函数第2张                break;
129基于Linux平台的高级IO扩展函数第2张
130基于Linux平台的高级IO扩展函数第2张            i = get_iov_tran_index(iov,iovcnt,all_tran,one_tran);
131基于Linux平台的高级IO扩展函数第2张            assert(i < iovcnt);
132基于Linux平台的高级IO扩展函数第2张            _iov[i].iov_base = iov[i].iov_base + one_tran;                
133基于Linux平台的高级IO扩展函数第2张            _iov[i].iov_len  = iov[i].iov_len - one_tran;
134基于Linux平台的高级IO扩展函数第2张
135基于Linux平台的高级IO扩展函数第17张        }
else if(0==ret)
136基于Linux平台的高级IO扩展函数第2张            break;
137基于Linux平台的高级IO扩展函数第12张        else{
138基于Linux平台的高级IO扩展函数第2张            if(tran) *tran = -1;
139基于Linux平台的高级IO扩展函数第2张            return false;
140基于Linux平台的高级IO扩展函数第17张        }

141基于Linux平台的高级IO扩展函数第17张    }
while(all_tran < all_cnt);
142基于Linux平台的高级IO扩展函数第2张
143基于Linux平台的高级IO扩展函数第2张    if(tran) *tran = all_tran;
144基于Linux平台的高级IO扩展函数第2张    return all_tran==all_cnt;
145基于Linux平台的高级IO扩展函数第4张}
   从以上代码可看出,readvn和writevn的实现并不是循环对每一个缓冲区简单地调用readn或writen,而是多次调用原生的readv或writev,因为对于读写多个缓冲区,使用readv或writev的效率通常要比多次调用read或write高,所以这样做就会尽可能减少系统调用的次数,提高效率。

免责声明:文章转载自《基于Linux平台的高级IO扩展函数》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇IDEA运行Tomcat,控制台日志乱码线程池ThreadPoolExcutor详解下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

MySQL锁详解

MySQL锁详解update语句执行流程MySQL的锁介绍按照锁的粒度来说,MySQL主要包含三种类型(级别)的锁定机制:全局锁:锁的是整个database。由MySQL的SQLlayer层实现的表级锁:锁的是某个table。由MySQL的SQLlayer层实现的行级锁:锁的是某行数据,也可能锁定行之间的间隙。...

高斯键盘设置指南

高斯键盘设置指南如何打开蓝牙模式电源:蓝牙需要电源。高斯GS87-D有两种通电方式:将键盘背面的开关转到on;使用USBType-C电源切换模式:Fn+P用于在有线模式和无线模式之间切换。按下Fn+P,Fn+PP右上角的键盘灯闪烁3次。有线模式和蓝牙模式相互切换。但是,没有指示灯指示当前模式是有线模式还是蓝牙模式如何连接蓝牙代码匹配:长按Fn+P,直到P键快...

【工具技巧】:sublime notepad++ 多行编辑

将光标定位到一行-˃ctrl+shift+↑↓, 上下移动一行。选择-˃ctrl+shift后+↑↓, 上下移动所选区域。再次按6:Ctrl+Shift+Enter在光标前插入一行。...

sqlite3 数据类型 批量插入

SQLite3采用动态数据类型。存储值的数据类型与值本身相关,而不是由其字段类型决定。SQLite3的动态数据类型可以向后兼容其他数据库常用的静态类型,这意味着在使用静态数据类型的数据库中使用的数据表也可以在SQLite3中使用。在SQLite2数据库中,除了声明为主键的INTEGER列外,任何列都可以存储属于任何存储类型的值。...

SQL Server 查看版本信息

SQLServer查看版本信息3种方法:1)使用命令行查看[Win+R]键-˃打开cmd2)使用SSMS查看打开并连接SSMS后查看3)通过服务器属性查看使用SSMS打开并连接指定数据库后,查看服务器属性...

解读阿里官方代码规范

作者将解释此代码规范的一些细节,包括作者的观点和想法,这些可以作为此代码规范扩展。该公众号共发表了五篇文章。这篇文章是一个集合,之前的一些文章已经过修改。在实际的编程过程中,作者可能会对类名的风格更加激进。根据阿里巴巴的规范,类名应该使用UpperCamelCase样式,并且必须遵循驼峰形式。但是,有以下例外:实际上,DO/BO/DTO/VO可能有UserV...