【问题标题】:File descriptor's offset is not moving when data is read using gzFile使用 gzFile 读取数据时文件描述符的偏移量不移动
【发布时间】:2019-09-21 05:59:50
【问题描述】:

我试图了解 glib 的 gzip 函数是如何工作的。所以我写了一个小程序来模拟我需要的东西。 我需要的是:
我需要打开和存储文件描述符,并且每当我想传递 fd 并使用复制的 fd 打开一个 gzFile 然后关闭它。以便我原来的 fd 保持开放以供将来阅读。
我已经阅读了 lib 手册 here!
它说:

"如果你想保持fd打开,使用fd = dup(fd_keep); gz = gzdopen(fd, mode);。复制的描述符应该被保存以避免泄漏,因为gzdopen在失败时不会关闭fd 。”

我正在执行与下面给出的代码的一部分相同的操作,我每次读取一个字符并关闭 fd 以便将来使用它。

这是我的 gzFile 代码不起作用:

#include <stdio.h>
#include <zlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

int ouFd1;

int inpFd1;

int main( int argc, char ** argv )
{   
    // Open a file to write the data
    inpFd1 = open("temp.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
    char* str = (char*)"Anil Prasad.";
    gzFile gzfile = gzdopen(inpFd1, "wb9h");
    int len = gzwrite(gzfile, &(str[0]), strlen(str));
    printf("written length: %d\n", len);
    gzclose(gzfile);


    // open a file to read the data.
    ouFd1 = open("temp.txt", O_RDONLY);

    char b[1]; 

    while (len > 0) { 
        int ouFd1_dup = dup(ouFd1);
        gzFile gzFile_2 = gzdopen(ouFd1_dup, "rb");
        int r = gzread(gzFile_2, &(b[0]), 1);
        printf("Character : %c\n", b[0]);
        len--;
        gzclose(gzFile_2);
    }

    fsync(ouFd1);
    close(ouFd1);
}

这个的输出是:

人物:A
性格:A
性格:A
性格:A
性格:A
性格:A
性格:A
性格:A
性格:A
性格:A
性格:A
字符:A

能否帮助我理解为什么在我执行 gzread() 后偏移量没有移动?
或者当我执行 gzclose(gzFile_2); 时它会被重置?

我也尝试过移动偏移:

    while (len > 0) { 
        int ouFd1_dup = dup(ouFd1);
        gzFile gzFile_2 = gzdopen(ouFd1_dup, "rb");
        int r = gzread(gzFile_2, &(b[0]), 1);
        gzseek(gzFile_2, 1, SEEK_CUR);
        printf("Character : %c\n", b[0]);
        len--;
        gzclose(gzFile_2);
    }

但结果还是一样!

有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: c compression gzip zlib


    【解决方案1】:

    您正在循环中打开和关闭文件 - 这会将文件指针重置为每次迭代的开头。

    我认为您不需要为您的工作复制文件描述符。您可以只使用 gzopen("temp.txt", "rb") 并使用给定的文件指针。

    您还使用大小为 1 的缓冲区 - 您可以先获取文件的大小并读入适当大小的缓冲区。

    我会这样做:

    // Create buffer
    char *buffer = new char[len+1];
    memset(buffer, 0, len);
    
    //Open file
    gzFile * file = gzopen("temp.txt", "rb");
    gzread(file, buffer, len);
    
    printf("%s\n", buffer);
    
    //Close file
    gzclose(file);
    
    //Delete buffer
    delete [] buffer;
    

    【讨论】:

    • 好的,你的意思是说,当我关闭重复的fd时,它是在重置原始fd的偏移量?这可能是可能的,但它没有显示在 glib 文档中。
    • 是的。关闭文件并再次打开它会将文件指针定位到开头。
    • 您正在循环中打开和关闭文件 - 这将在每次迭代时将文件指针重置为开头。 请注意,int ouFd1_dup = dup(ouFd1); 不会重置ouFd1_dup 的文件指针从 dup()'d 文件描述符读取将更改原始描述符的偏移量 - dup()'d 描述符实际上是指 original 描述符,因此更改为ouFd1_dup 的偏移量将改变ouFd1 的偏移量,并且偏移量变化将持续到每个循环迭代之后。如果偏移量被重置,很可能是由gzdopen 完成的。
    猜你喜欢
    • 2023-03-17
    • 1970-01-01
    • 2017-07-14
    • 2013-08-19
    • 2013-11-08
    • 1970-01-01
    • 2012-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多