C ++: fread () возвращает ненулевое значение, но только вставляет нули в буфер - PullRequest
0 голосов
/ 03 апреля 2012

Я использую fread () в C ++ для чтения очень больших двоичных файлов (100 МБ-2 ГБ). Бинарные файлы изначально написаны на C ++ путем вывода серии «пакетов». Пакеты состоят из структуры заголовка (которая содержит поле размера), которая записывается непосредственно в файл, а затем двоичное содержимое с размером, равным размеру, записанному в заголовок. При чтении файлов пакеты зацикливаются, заголовок считывается в структуру, а содержимое считывается в пустой указатель размера, указанного в заголовке.

Это известный метод работы, уже реализованный в других инструментах (то есть я могу проверить файлы, которые пытаюсь прочитать). Предположим, что все файлы, с которыми мы работаем, проверены. По крайней мере, в одном файле моя реализация чтения двоичного файла работает правильно.

Тем не менее, с другим файлом fread () начинает работать напрасно без видимой причины. После многих успешных чтений я чисто прочитал часть заголовка пакета, используя:

if (sizeof(stHdr) != fread((void *)&stHdr, 1, sizeof(stHdr), fi))

Под чистым чтением я имею в виду, что fread () возвращает «sizeof (stHdr)», как и ожидалось, а feof (fi) и ferror (fi) возвращают 0. Однако ... stHdr полностью заполнен всеми нулями; значение каждого поля в stHdr содержит 0x0. Я проверил двоичный файл, чтобы он был правильно сформирован и имел данные в тот момент, когда я читаю.

Кто-нибудь видел это раньше или знает, что может быть причиной?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 04 апреля 2012

Проблема оказалась классическим случаем PEBKAC ...

Видимо, мой бинарный файл в какой-то момент стал повреждённым, и на самом деле в нем было множество нулей. Я скопировал его прямо из репозитория, и файл был проверен перед тем, как помещен в репозиторий, поэтому я предположил, что это хорошо. Очевидно, что-то плохое случилось с моей локальной версией файла и стало источником моих проблем.

0 голосов
/ 03 апреля 2012

Если размер ваших файлов превышает 2 ГБ, вам необходимо включить поддержку больших файлов.

Быстрый и простой способ сделать это - скомпилировать с -D_FILE_OFFSET_BITS=64.Более точные способы и более подробную информацию см. http://www.suse.de/~aj/linux_lfs.html

...