2011-08-10 91 views
2


我已经这块Ç代码:读取二进制文件的全部内容

[...] 
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 *?

回答

2

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

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

+0

actualy简单'info.st_size'足够在这种情况下 –

1

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

+0

'NULL'是一个空指针* *不变。 C字符串是空终止的,或者更准确地说是''\ 0''终止,而不是NULL终止。 –

1

您成功加载了整个文件。

但它包含零和零意味着以(:) :)结尾的字符串结束。 strlen()对你没有任何好处。

1

你在做什么似乎确定,问题在于strlen的......它停止,当它遇到“\ 0”计数。 fread将返回它写入content的元素数。

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()和实际读取文件之间的文件大小可能已更改。