【问题标题】:Read the full content of a binary file读取二进制文件的全部内容
【发布时间】:2011-08-10 15:19:42
【问题描述】:


我有这段 C 代码:

[...]
struct stat info;
char *filename = "just_a_binary_file";
stat(filename, &info);
printf("FILE SIZE: %d\n", info.st_size);

char *content = (char *)malloc(info.st_size * sizeof(char *));
FILE *fp = fopen(filename, "rb");
fread(content, info.st_size, 1, fp);
fclose(fp);

printf("STRING LENGTH: %d\n", strlen(content));
[...]

输出是:

FILE SIZE: 20481
STRING LENGTH: 6

问题是文件包含一些零字节,当我将文件内容放入变量 char* 时,字符串在第一次出现 '\0' 时被截断(精确为 chr(0))。

问题是如何将完整的二进制内容放入变量 char* 中?

【问题讨论】:

    标签: c file binary


    【解决方案1】:

    这是您的代码的修改版本。和你的比较一下。

    struct stat info;
    const char *filename = "just_a_binary_file";
    if (stat(filename, &info) != 0) {
        /* error handling */
    }   
    printf("FILE SIZE: %lu\n", (unsigned long)info.st_size);
    
    char *content = malloc(info.st_size);
    if (content == NULL) {
        /* error handling */
    }   
    FILE *fp = fopen(filename, "rb");
    if (fp == NULL) {
        /* error handling */
    }
    /* Try to read a single block of info.st_size bytes */
    size_t blocks_read = fread(content, info.st_size, 1, fp);
    if (blocks_read != 1) {
        /* error handling */
    }
    fclose(fp);
    
    /*
     * If nothing went wrong, content now contains the
     * data read from the file.
     */
    
    printf("DATA LENGTH: %lu\n", (unsigned long)info.st_size);
    

    请注意,这种方法在某些情况下仍然容易出错。例如,stat() 为您提供在您调用 stat() 时文件的大小。在调用 stat() 和实际读取文件之间,文件的大小可能发生了变化。

    【讨论】:

      【解决方案2】:

      首先,你分配了太多的内存。 info.st_size * sizeof(char) 就够了。您存储的是字符,而不是指针。

      然后您需要存储文件大小并使用内存函数而不是字符串函数。包含空字节的数据块不是每个定义的字符串。所以除非使用已知的文件大小,否则不可能得到它的长度。

      【讨论】:

      • 在这种情况下,实际上只需 info.st_size 就足够了
      【解决方案3】:

      在我看来,您确实将完整的二进制文件读入了content。二进制数据不是字符串数据。字符串以 NULL 结尾。当您在调试器中检查内容时,是的,它看起来被截断了,但实际上,它的大小为 20481 字节。查看内存中的content,您应该会看到所有内容。

      【讨论】:

      • NULL 是一个空的 pointer 常量。 C 字符串以 null 结尾,或者更准确地说是 '\0' 终止,而不是 NULL 终止。
      【解决方案4】:

      您已成功加载整个文件。

      但它包含零,并且零表示 (:)) 以零结尾的字符串的结尾。 strlen() 对你没有任何好处。

      【讨论】:

        【解决方案5】:

        你正在做的似乎没问题,问题出在 strlen 上......当它遇到'\0'时它停止计数。 fread 将返回它写入content 的元素数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-12-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多