c read()导致错误的文件描述符错误

时间:2011-06-30 17:00:09

标签: c file-descriptor

这方面的背景是程序基本上是通过文件流读取,一次读取4K块,寻找某种模式。它首先读取4k,如果没有找到那里的模式,它会启动一个循环,读取下一个4k块(冲洗并重复直到找到EOF或模式)。 在许多文件上代码工作正常,但有些文件出错。

下面的代码显然是高度编辑的,我知道这可能很烦人,但它包括引用文件描述符或文件本身的所有行。我知道你不想接受我的话,因为我是那个有问题的人......

在哭泣寻求帮助之前完成了一些小作业,我发现:

  1. 文件描述符总是= 6(对于正在运行的文件也是6),并且该数字在执行期间不会被更改。不知道这是否有用。

  2. 通过在访问文件描述符的每个操作之后插入print语句,我还发现成功的文件经历了以下循环“open-read-close-close”(即在第一个中找到了模式) 4K) 不成功的文件变为“open-read-read ERROR(Bad File Descriptor)-close”。因此没有过早关闭,并且它在第一次读取成功,但第二次读取导致错误文件描述符错误。

  3. int function(char *file)
    {
    
    int len, fd, go = 0;
    char buf[4096];
    
    if((fd = open(file, O_RDONLY)) <= 0)
    {
        my_error("Error opening file %s: %s", file, strerror(errno));
        return NULL;
    }
    
    //first read
    if((len = read(fd, buf, 4096)) <= 0)
    {
        my_error("Error reading from file %s: %s", file, strerror(errno));
        close(fd); return NULL;
    }
    
    //pattern-searching
    
    if(/*conditions*/)
    {
        /* we found it, no need to keep looking*/
        close(fd);
    }
    
    else
    {
        //reading loop
        while(!go)
        {
            if(/*conditions*/)
            {
                my_error("cannot locate pattern in file %s", file);
                close(fd); return NULL;
            }
    
            //next read
            if((len = read(fd, buf, 4096)) <= 0) /**** FAILS HERE *****/
            {
                my_error("Error reading from file, possible bad message %s: %s",
                    file, strerror(errno));    
                close(fd); return NULL;
            }
    
            if(/*conditions*/)
            {
                close(fd);
                break;
            }
    
            //pattern searching
    
            if(/*conditions*/)
            {
                 /* found the pattern */
                go++; //break us out of the while loop
    
                //stuff
    
                close(fd);
            }
            else
            {
                //stuff, and we will loop again for the next chunk
            }
        } /*end while loop*/
    }/*end else statement*/
    
    close(fd);
    }
    

    尽量不要担心模式读取逻辑 - 所有操作都在char缓冲区上完成,而不是在文件上完成,所以它应该对这个问题没有影响。

1 个答案:

答案 0 :(得分:2)

EOF返回0(如果......&lt; = 0则进入),但不设置errno,其中可能包含过时的代码。

单独测试0和负(错误,-1)值。


关于“strace”:我在家里和之前的工作中使用过一点。不幸的是,它并没有安装在我目前的工作环境中。当它可用时,它是一个有用的工具。在这里,我用提问者采取了“让我们阅读精细手册”(man read)的方法: - )