从文件中读取和写入时无限循环 - C

时间:2018-04-14 23:20:08

标签: c file-io

我试图从输入文件中读取并最终反转它读取的缓冲区并将其写入输出文件。但就目前而言,我正在测试,看看我读取的缓冲区是否会将其输出到输出文件,到目前为止它还没有,并且我得到了一个无限循环。缓冲区应该读取PAGESIZE字节(从调用sysconf())并且如果文件输出大于缓冲区,则应首先将缓冲区写入输出文件,然后刷新并再次重用以获取其余的输入,直到文件描述符返回0表示没有数据。这就是我到目前为止所做的:

int fdRead = open(inputFile, O_RDONLY);
if (fdRead == -1)
    err_sys("Error reading input file '%s', check spelling?\n", inputFile);
int fdWrite = open(outputFile, O_WRONLY | O_CREAT | O_TRUNC, 0644); //overwrites file if it exists
if (fdWrite == -1)
    err_sys("Error creating output file '%s'\n", outputFile);
while (1) {
    read(fdRead, buf, size);
    if (fdRead == 0)
        break;
    if (fdRead == -1)
        err_sys("Error reading from input file '%s'\n", inputFile);
    lseek(fdRead, size, SEEK_CUR);
    if (fdRead == -1)
        err_sys("Error reading from input file '%s'\n", inputFile);
    write(fdWrite, buf, size);
    if (fdWrite == -1)
        err_sys("Error writing to output file '%s'\n", outputFile);
    lseek(fdWrite, size, SEEK_CUR);
    if (fdWrite == -1)
        err_sys("Error writing to output file '%s'\n", outputFile);
    memset(buf, '\0', size);
}
close(fdRead);
close(fdWrite);

我认为fdRead永远不会返回0,因此不会退出循环。我的问题是如何解决这个问题?

p.s:size是来自sysconf()的调用,它获取PAGESIZE,例如

size = sysconf(_SC_PAGESIZE);

inputFile和outputFile都是char *,我测试过它们返回并存储好字符串。

2 个答案:

答案 0 :(得分:2)

将评论转录成答案。

您需要从read()捕获返回值 - 您忽略它并在read()之后测试文件描述符是0还是负数。

  

因此,如果我执行int bytesRead之类的操作,然后针对if (bytesRead == 0)而不是if (fdRead == 0)进行测试,那么这应该可以解决我的问题吗?

是的,你需要这样的东西:

int nbytes = read(fdRead, buf, size);
if (nbytes <= 0) break;

您应该在nbytes电话中使用正面write();您可能无法获得read()填充的所有大小字节。

在读取错误后测试文件描述符(在正常情况下它不会改变),忽略read()返回的值是错误的,并且不使用read()返回的值在调用write()时是错误的。

  

好的,它应该是write(fdWrite, buf, nbytes)

是的,它应该是

int obytes;
if ((obytes = write(fdWrite, buf, nbytes)) != nbytes)
{
   …oops — short write …
}

您可以决定对短写入的适当响应(正值,但不是您希望写入的字节数)。如果您正在写入套接字,那么尝试再次写入未写入的数据部分可能是合适的(这就是使用obytes来捕获成功写入的字节数的原因)。如果您正在写入磁盘文件,这可能意味着没有剩余空间,因此再次尝试没有任何意义(小点)。如果obytes为负数,则表示您有写入错误;试图继续下去通常没什么意义。

  

这一切都有很大帮助,似乎工作正常。我只遇到另一个问题。我在一个大文件(Alice in Wonderland文本文件)上测试了这个,输出文件几乎是整个文件,但是切断了最后两段左右。 ...

您需要查看代码中lseek()操作的原因。它们都不是必要的,两者都是可疑的。我认为lseek()上的fdRead()表示您错过了每个size字节的大块文本;我认为lseek()上的fdWrite()表示您将size空字节插入到输出文件中。

答案 1 :(得分:0)

            /*Here's the code which may help for that.i havemodified in it for your need.*/

        int fdRead = open(inputFile,                                             O_RDONLY);
        int Ret_Val;    
        if (fdRead == -1)
        err_sys("Error reading input file'%s',check spelling?\n", 
        inputFile );
        int fdWrite = open(outputFile, O_WRONLY | O_CREAT 
       | O_TRUNC, 0644); //overwrites file if it exists
        if (fdWrite == -1)
        err_sys("Error creating output file '%s'\n", outputFile);
        while (1) {
        Ret_Val=read(fdRead, buf, size);
        if (Ret_Val == 0)
            break;
        if (Ret_Val == -1)
        err_sys("Error reading from input file'%s'\n",inputFile);
        lseek(fdRead, size, SEEK_CUR);
        if (Ret_Val == -1)
            err_sys("Error reading from input file'%s'\n",             
        inputFile );
        Ret_Val=write(fdWrite, buf, size);
        if (Ret_Val == -1)
        err_sys("Error writing to output file'%s'\n",outputFile);
        lseek(fdWrite, size, SEEK_CUR);
        if (Ret_Val == -1)
        err_sys("Error writing to output file'%s'\n",outputFile);
        memset(buf, '\0', size);
        }
        close(fdRead);
        close(fdWrite);