Прочитайте полное содержание двоичного файла - PullRequest
2 голосов
/ 10 августа 2011


У меня есть этот кусок 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 ]

2 голосов
/ 10 августа 2011

Прежде всего, вы выделяете слишком много памяти. info.st_size * sizeof(char) достаточно. Вы храните символы, а не указатели.

Затем вам нужно сохранить размер файла и использовать функции памяти вместо строковых функций. Большой блок данных, который содержит нулевые байты, не является строкой в ​​определении. Поэтому невозможно получить его длину, кроме как с использованием уже известного размера файла.

1 голос
/ 10 августа 2011

Вот модифицированная версия вашего кода.Сравните это с вашим.

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() и чтением файла.

1 голос
/ 10 августа 2011

То, что вы делаете, кажется нормальным, проблема в strlen ... он перестает считать, когда встречает '\ 0'.fread вернет количество записанных элементов в content.

1 голос
/ 10 августа 2011

Вы успешно загрузили весь файл.

Но он содержит ноль, а ноль означает конец строки (:)) с нулем в конце. strlen() не принесет вам пользы.

1 голос
/ 10 августа 2011

Мне кажется, что вы прочитали полный двоичный файл в content.Двоичные данные не являются строковыми данными.Строки обнуляются.Когда вы просматриваете содержимое в отладчике, да, оно выглядит усеченным, но на самом деле его размер составляет 20481 байт.Посмотрите на content в памяти, и вы должны увидеть все это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...