阅读二进制文件的完整内容

时间:2011-08-10 15:19:43

标签: c file binary


我有这段 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 *?

5 个答案:

答案 0 :(得分:2)

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

然后您需要存储文件大小并使用内存函数而不是字符串函数。包含空字节的数据块不是每个定义的字符串。因此除了使用已知的文件大小之外,不可能获得它的长度。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

您已成功加载整个文件。

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

答案 3 :(得分:1)

你正在做什么似乎没问题,问题在于strlen ......当它遇到'\ 0'时会停止计数。 fread会将其撰写的元素数量返回给content

答案 4 :(得分: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()和实际读取文件之间,文件的大小可能已经改变。