读取二进制文件的全部内容

3
我来翻译了:


我有这段 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个回答

4
这里是您代码的修改版本。请与您的代码进行比较。
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) 足够了。您要存储字符,而不是指针。

然后,您需要存储文件大小并使用内存函数而不是字符串函数。包含空字节的数据块按定义不是字符串。因此,除非使用已知的文件大小,否则无法获取其长度。


1
实际上,在这种情况下,仅使用info.st_size就足够了。 - Vinicius Kamakura

1

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


NULL是一个空指针常量。C字符串以空字符结尾,更准确地说是以'\0'结尾,而不是以NULL结尾。 - Keith Thompson

1

您已成功加载整个文件。

但它包含零,而零意味着字符串的结束。 strlen() 对您没有任何帮助。


1

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接