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

Posted

技术标签:

【中文标题】c read() 导致错误的文件描述符错误【英文标题】:c read() causing bad file descriptor error 【发布时间】:2011-06-30 17:00:09 【问题描述】:

上下文是程序基本上是读取文件流,一次读取 4K 块,寻找特定模式。它从读取 4k 开始,如果在那里找不到模式,它会启动一个循环,读取下一个 4k 块(冲洗并重复,直到找到 EOF 或模式)。 在许多文件上,代码工作正常,但有些文件出现错误。

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

在哭求帮助之前做了一点功课,我发现:

    文件描述符恰好总是 = 6(对于正在工作的文件,它也是 6),并且该数字在执行期间不会改变。不知道这是否有用。

    通过在每个访问文件描述符的操作之后插入打印语句,我还发现成功的文件会经历以下循环“打开-读取-关闭-关闭”(即模式在第一个4K) 不成功的文件会“打开-读取-读取错误(错误文件描述符)-关闭”。所以不会过早关闭,第一次读取成功,但第二次读取会导致 Bad File Descriptor 错误。

.

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 缓冲区上完成,而不是在文件上完成,所以它应该不会影响这个问题。

【问题讨论】:

我不确定为什么读取会出现该错误,因为 fd 在代码中的该点仍应打开并有效。无论如何,如果您不寻找下一个 4096 字节,您将始终读取文件的第一部分。 【参考方案1】:

EOF 返回 0(属于 if ...

尝试分别测试 0 和负(错误,-1)值。


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

【讨论】:

read 根本没有失败。它以 0 (EOF) 的结果成功。因此errno 的值与read 完全无关。 顺便说一句,使用strace 进行调试会让这一切立即显现出来。 哈!我没有注意到“小于或等于”。

以上是关于c read() 导致错误的文件描述符错误的主要内容,如果未能解决你的问题,请参考以下文章

Boost asio异步操作坏文件描述符

select.select() arguments 文件描述符不能是负整数错误

APUE第3章 文件I/O

多次使用 socketpair 函数的文件描述符时出现“错误的文件描述符”错误

sqlite3无法在终端运行

错误系统:9:错误的文件描述符(BOOST::FileSystem)