2011-08-10 29 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()和實際讀取文件之間的文件大小可能已更改。