linux 下read函数返回值分析_Devin_新浪博客

原文出处: http://blog.chinaunix.net/space.php?uid=20558494&do=blog&id=2803003
read函数是Linux下不带缓存的文件I/O操作函数之一,所谓的不带缓存是指一个函数只调用系统中的一个函数。另外还有open、write、lseek、close,它们虽然不是ANSI C的组成部分,但是POSIX的组成部分。
 
    在对read的使用过程中,发现对其返回值的处理比较重要,这里做一下总结。
 
read函数原型:
          ssize_t read(int fd,void *buf,size_t count)
 
函数返回值分为下面几种情况:

1、如果读取成功,则返回实际读到的字节数。这里又有两种情况:一是如果在读完count要求字节之前已经到达文件的末尾,那么实际返回的字节数将 小于count值,但是仍然大于0;二是在读完count要求字节之前,仍然没有到达文件的末尾,这是实际返回的字节数等于要求的count值。

2、如果读取时已经到达文件的末尾,则返回0。

3、如果出错,则返回-1。

    这样也就是说分为>0 <0 =0三种情况进行讨论。在有的时候,<0 =0可以合为一种情况进行处理。这要根据程序的需要进行处理。

实例分析:

-------------------------------

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

#define MAXSIZE 35

int main(void)
{
        int i,j,fd,size,len;
        char *buf="Hello!I`m writing to this file!";
        char buf_r[MAXSIZE];
        len=strlen(buf);

        //open
        if((fd=open("/tmp/hello.c",O_CREAT | O_TRUNC | O_RDWR,0666))<0) {
                perror("open:");
                exit(1);
        }
        else
                printf("Open file:hello.c %d\n",fd);

        //write
        if((size=write(fd,buf,len))<0){
                perror("write:");
                exit(1);
        }
        else
                printf("Write:%s\n\n\n",buf);

        //test-read
        printf("Now test starts...\n\n");
       for(i=0;i<20;i++){
               lseek(fd,0,SEEK_SET);
                for(j=0;j<MAXSIZE;j++)
                        buf_r[j]=0;
                if((size=read(fd,buf_r,MAXSIZE-i))<0){
                perror("read:");
                exit(1);
                }
                else {
               buf_r[MAXSIZE-i]='\0';
                printf("string-len=%d,count=%d,size=%d\n",len,MAXSIZE-i,size);
                printf("read from file:%s \n",buf_r);
                }
        }
        printf("\n\nNow test stops...\n");

        //close
        if(close(fd)<0){
                perror("close:");
                exit(1);
        }
        else
                printf("close hello.c\n");
        exit(0);
}

-------------------------------

结果如下:

-------------------------------

[armlinux@lqm test-read]$ ./write
Open file:hello.c 3
Write:Hello!I`m writing to this file!


Now test starts...

string-len=31,count=35,size=31
read from file:Hello!I`m writing to this file!
string-len=31,count=34,size=31
read from file:Hello!I`m writing to this file!
string-len=31,count=33,size=31
read from file:Hello!I`m writing to this file!
string-len=31,count=32,size=31
read from file:Hello!I`m writing to this file!
string-len=31,count=31,size=31
read from file:Hello!I`m writing to this file!
string-len=31,count=30,size=30
read from file:Hello!I`m writing to this file
string-len=31,count=29,size=29
read from file:Hello!I`m writing to this fil
string-len=31,count=28,size=28
read from file:Hello!I`m writing to this fi
string-len=31,count=27,size=27
read from file:Hello!I`m writing to this f
string-len=31,count=26,size=26
read from file:Hello!I`m writing to this 
string-len=31,count=25,size=25
read from file:Hello!I`m writing to this
string-len=31,count=24,size=24
read from file:Hello!I`m writing to thi
string-len=31,count=23,size=23
read from file:Hello!I`m writing to th
string-len=31,count=22,size=22
read from file:Hello!I`m writing to t
string-len=31,count=21,size=21
read from file:Hello!I`m writing to 
string-len=31,count=20,size=20
read from file:Hello!I`m writing to
string-len=31,count=19,size=19
read from file:Hello!I`m writing t
string-len=31,count=18,size=18
read from file:Hello!I`m writing 
string-len=31,count=17,size=17
read from file:Hello!I`m writing
string-len=31,count=16,size=16
read from file:Hello!I`m writin


Now test stops...
close hello.c

-------------------------------

现象:

测试部分中,string-len是测试文件内容的长度,count是要求读取的字节数,size是实际读取的字节数。可以观察出,开始 count>string-len,所以虽然读取成功,但是返回的实际字节数要小于要求的字节数。从count=string-len之后,实际返 回的字节数等于要求的字节数。

问题分析:

1、每次执行read函数之前,保证指定好起始位置,并且对buf初始化。

如果将

                lseek(fd,0,SEEK_SET);
                for(j=0;j<MAXSIZE;j++)
                        buf_r[j]=0;

移到for循环外,那么只能保证i=0时完成了上述工作。这是已经读到文件的末尾,所以后面的size应该全部为零。因为没有对buf_r初始化,所以读取内容没有变化。具体结果如下:

-------------------------------

[armlinux@lqm test-read]$ ./write
Open file:hello.c 3
Write:Hello!I`m writing to this file!


Now test starts...

string-len=31,count=35,size=31
read from file:Hello!I`m writing to this file!
string-len=31,count=34,size=0
read from file:Hello!I`m writing to this file!
string-len=31,count=33,size=0
read from file:Hello!I`m writing to this file!
...

...
Now test stops...
close hello.c

-------------------------------

2、对于一个数组,总是要自动分配一个\0作为结束,所以实际有效的buf长度就成为buf_r-1了。在本例中,倘若把MAXSIZE设为31,即等于string-len的长度。那么当你读取31个字符时,\0就没有了地方。如果把buf_r[MAXSIZE-i]='\0';去掉,那么在显示后面就会出现乱码现象。

-------------------------------

[armlinux@lqm test-read]$ ./write
Open file:hello.c 3
Write:Hello!I`m writing to this file!


Now test starts...

string-len=31,count=31,size=31
read from file:Hello!I`m writing to this file?B
B


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值