尝试使用read()系统调用读取文件时,程序卡住了

时间:2016-10-14 20:29:47

标签: c linux file-io system system-calls

这是我的代码段:

int fd;
bufsize = 30;
char buf[bufsize];
char cmd[100] = "file.txt";
int newfd = 1;

if (fd = open(cmd,O_RDONLY) >=0){
    puts("wanna read");
    while (read(fd,&bin_buf,bufsize)==1){
        puts("reading");
        write(newfd,&bin_buf,bufsize);
    }
    close(fd);
}

所以这里程序打印"wanna read"但从不打印"reading"。我也尝试使用nonblock标志打开,但没有用。有谁能够帮我?我必须仅使用open()read()系统调用。谢谢。 编辑:我在代码中做了一些澄清。实际上我写的newfd是套接字描述符,但我不认为这对于这个问题很重要,因为它坚持read之前的write

3 个答案:

答案 0 :(得分:2)

第一个问题是你的if声明。您忘记使用足够的括号,因此如果open()有效,则读取尝试从文件描述符1(即标准输出)读取。如果这是你的终端(它可能是)在Unix机器上,那么它可行 - 虽然可能是令人惊讶的;该程序正在等待您输入内容。

修复:使用括号!

if ((fd = open(cmd, O_RDONLY)) >= 0)

分配是在比较之前而不是之后完成的。

我顺便观察到你没有展示你如何设置cmd,但如果你看到'想要阅读'的消息,那一定是好的。您没有显示newfd的初始化方式;也许那是1

您还遇到了“read()调用返回的内容”的问题。你可能需要:

int fd;
char buf[bufsize];
int newfd = 1;

if ((fd = open(cmd, O_RDONLY)) >= 0)
{
    puts("wanna read");
    int nbytes;   // ssize_t if you prefer
    while ((nbytes = read(fd, buf, sizeof(buf))) > 0)
    {
        puts("reading");
        write(newfd, buf, nbytes);
    }
    close(fd);
}

您可以通过原始if键入某些内容('Surprise'或'终端文件描述符通常是可读写的'或其他内容)来演示我的主要观察结果,但我的循环体然后将其写入某处。< / p>

答案 1 :(得分:1)

read返回从文件读取的字节数,如果必须读取的文件的剩余部分短于bufsize,则可以是bufsize或更少。

在你的情况下,很可能bufsize大于1且文件大于1个字节,因此while循环的条件被评估为false,代码被跳过到文件关闭的位置。

您应该检查是否有更多要读取的字节

while( read(fd,&bin_buf,bufsize) > 0 ) {

答案 2 :(得分:1)

您的read()调用尝试读取bufsize个字节并返回实际读取的字节数。除非bufsize ==,否则read()将不会返回1,因此几乎总是会跳过该块,并且不会写入任何内容。

另请注意if (fd = open(cmd, O_RDONLY) >= 0)不正确,并将fd设置为1,标准输出的句柄(如果文件存在),导致read失败作为标准输入很可能无法阅读。

请注意,在某些环境中使用read系统调用进行阅读非常棘手,因为-1的返回值可以重新启动。

以下是改进版本:

int catenate_file(const char *cmd, int newfd, size_t bufsize) {
    int fd;
    char buf[bufsize];

    if ((fd = open(cmd, O_RDONLY)) >= 0) {
        puts("wanna read");
        ssize_t nc;
        while ((nc = read(fd, buf, bufsize)) != 0) {
            if (nc < 0) {
                if (errno == EINTR)
                    continue;
                else
                    break;
            }
            printf("read %zd bytes\n", nc);
            write(newfd, buf, nc);
        }
        close(fd);
        return 0;
    }
    return -1;
}