完整的读写函数

1.写函数write

1  #include <unistd.h>
2   ssize_t write(int fd, const void *buf, size_t count);

write函数将buf中的count字节内容写入到文件描述符fd中。

成功时返回所写入的字节数。返回0表示什么也没有写入,失败时返回-1。并设置errno变量。

在网络程序中,当我们向套接字文件描述符写入时有两种可能:

①write的返回值大于0,表示定稿了部分或者是全部的数据。

②返回值小于0,此时出现了错误:

为了处理以上的情况,我们自己编写一个写函数来处理这几种情况

 

 1 /**
 2  *my_write函数将buf中的count字节内容写入到文件描述符fd中
 3  *函数成功时,返回 0,失败时返回 -1
 4  */
 5 int my_write( int fd, void *buf, size_t count )
 6 {
 7   size_t bytes_left;    //还没有写入的字节数
 8   size_t written_bytes; //已经写入的字节数
 9   char *ptr;            //从该位置起写入
10   
11   //写入之前的初始化
12   ptr = buf;         //刚开始时,从buf的起始位置开始写入
13   bytes_left = count;   //刚开始时,全部都还没有写入
14   
15   //写入操作
16   while( bytes_left > 0 ) // 当来还有未写入的数据时,执行循环
17   {
18     //开始把数据写入到fd
19     written_bytes = write(fd, ptr, bytes_left); //返回实际写入的字节数
20     
21     // 写入不成功时进行处理
22     if( written_bytes <= 0 ) 
23     {
24       if( errno == EINTR ) // 如果是中断错误,设置写入字节数为0(written_bytes = 0)则重启写入操作
25       {
26         written_bytes = 0; // 表示没有写入
27         continue;          // 提前结束此次循环,重启写入操作
28       }
29       else                // 如果是其他错误,则退出程序
30       {
31         perror("write error ");
32         return -1;
33       }
34     }
35     
36     //写入成功时,重新调剩下的要写入的字节数和要写入数据的位置
37     bytes_left -=written_bytes; //扣除已写入的字节数
38     ptr+=written_bytes;         //ptr指向下一次要写入的数据起始位置
39   }
40   
41   return 0;
42 }

 

 

 

2.读函数read

1 #include <unistd.h>
2 ssize_t read(int fd, void *buf, size_t count);

read函数从fd中读取count字节的内容,存储在buf中。

函数成功时,返回实际读的字节数,如果返回0表示已经读到文件的末尾。

返回值小于0表示出现了错误,设置errno:

①如果错误为ENITR说明读是由中断引起的,应当重启读操作。

②如果为其他类型的错误,则程序应该退出并用perror()给出出错信息。具体错误详见http://man7.org/linux/man-pages/man2/read.2.html

为了处理以上的情况,我们自己编写一个读函数来处理这几种情况

 1 /**
 2  *my_read 函数从fd中读取count字节的数据,并存储到buf中
 3  *函数成功时返回读取的字节数,失败时返回 -1
 4  */
 5 int my_read( int fd, void *buf, size_t count )
 6 {
 7   size_t bytes_left; //还没有读取的字节数
 8   size_t bytes_read; //已经读取的字节数
 9   char   *ptr;       //存储数据的起始位置
10   
11   //读取数据之前的初始化
12   bytes_left = count;//还有count字节的数据没有读取
13   ptr = buf;         //读取到的数据存储在buf中
14   //读取数据
15   while( bytes_left > 0 ) // 数据读取没有全部完成,执行循环
16   {
17     bytes_read = read(fd, ptr, bytes_left); // 返回实际读取的数据的长度
18     
19     // read函数调用出现错误,进行处理
20     if( bytes_read < 0 ) 
21     {
22       if( errno == EINTR ) // 中断引起的错误, 重新启动读取操作
23       {
24         bytes_read = 0;    // 没有读取到数据
25         continue;          // 提前结束本次循环
26       }
27       else
28       {
29         perror("read error ");
30         return -1;         //其他错误则退出程序
31       }
32     }
33     else if( bytes_read == 0 )
34     {
35       break;               //返回0表示fd中已经没有数据了
36     }
37     
38     //重新调整还未读取的数据的字节数和数据的存储位置
39     bytes_left -=bytes_read; //扣除已读取的数据 
40     ptr += bytes_read;       //下一次存储所读取数据的位置
41   }
42   return (count - bytes_left);
43 }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2012-08-18 15:30  blankqdb  阅读(499)  评论(0)    收藏  举报