加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

linux 下read函数返回值分析

(2011-11-29 11:17:23)
标签:

linux

read

返回值

杂谈

分类: ARM-编程笔记
原文出处: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

阅读 收藏 喜欢 打印举报/Report
前一篇:阻塞与非阻塞
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有