feof() возвращает true, когда EOF не достигнут

Я пытаюсь прочитать из файла с определенным смещением (упрощенная версия):

typedef unsigned char u8;
FILE *data_fp = fopen("C:\\some_file.dat", "r");
fseek(data_fp, 0x004d0a68, SEEK_SET); // move filepointer to offset
u8 *data = new u8[0x3F0];
fread(data, 0x3F0, 1, data_fp);
delete[] data;
fclose(data_fp);

Проблема заключается в том, что данные будут содержать не 1008 байт, а 529 (кажется случайным). Когда он достигнет 529 байт, вызовы feof(data_fp) начнут возвращать значение true.

Я также пытался читать более мелкие фрагменты (по 8 байт за раз), но похоже, что он нажимает EOF, когда его еще нет.

Простой просмотр в шестнадцатеричном редакторе показывает, что осталось много байтов.


person Daniel Sloof    schedule 14.12.2010    source источник
comment
@pmg, использование malloc/free не решит мою проблему, но подойдет вам :)   -  person Daniel Sloof    schedule 14.12.2010
comment
в C (я не знаю C++) я бы попробовал открыть файл в двоичном режиме   -  person pmg    schedule 14.12.2010
comment
@pmg, блин! это было так просто ... пожалуйста, создайте ответ, и я приму его.   -  person Daniel Sloof    schedule 14.12.2010
comment
Что находится по смещению 0x004d0a68 + 529?   -  person Eugen Constantin Dinca    schedule 14.12.2010
comment
+1 за xvi. Вы тоже редактируете с помощью vi?   -  person pmg    schedule 14.12.2010


Ответы (4)


Открытие файла в текстовом режиме, как вы делаете, заставляет библиотеку преобразовывать часть содержимого файла в другие вещи, потенциально вызывая необоснованный EOF или неверные вычисления смещения.

Откройте файл в двоичном режиме, передав опцию «b» вызову fopen

fopen(filename, "rb");
person pmg    schedule 14.12.2010

Записывается ли файл параллельно каким-либо другим приложением? Возможно, есть состояние гонки, так что файл заканчивается там, где останавливается чтение, когда чтение выполняется, но позже, когда вы проверяете его, остальное было записано. Это также объясняет случайность.

person unwind    schedule 14.12.2010
comment
Неа! оно читалось другим приложением, но его закрытие или даже копирование файла и изменение пути дает мне тот же результат... как ни странно, случайное число (529) всегда одинаково - person Daniel Sloof; 14.12.2010

Возможно, это разница между текстовым и двоичным файлом. Если вы работаете в Windows, символы новой строки — это CRLF, то есть два символа в файле, но при чтении они преобразуются только в один. Попробуйте использовать fopen(..., "rb")

person Milan Babuškov    schedule 14.12.2010

Я не вижу вашей ссылки с работы, но если ваш компьютер утверждает, что байтов больше не существует, я склонен в это поверить. Почему бы вам не распечатать размер файла, а не делать что-то вручную в шестнадцатеричном редакторе?

Кроме того, вам лучше использовать ввод-вывод уровня 2, f-вызовы - это древнее уродство C, и вы используете C++, поскольку у вас есть новый.

int fh =open(filename, O_RDONLY);
struct stat s;
fstat(fh, s);
cout << "size=" << hex << s.st_size << "\n";

Теперь выполните поиск и чтение, используя вызовы ввода-вывода уровня 2, которые в любом случае быстрее, и давайте посмотрим, каков размер файла на самом деле.

person Dov    schedule 14.12.2010
comment
В большинстве случаев f-вызовы быстрее, потому что они буферизуются, а низкоуровневые не буферизуются. Однако в данном случае это не имеет значения, так как есть только одно чтение. - person Sergei Tachenov; 14.12.2010
comment
ЕСЛИ вам нужна скорость, не используйте старый, грубый C API, в котором слой за слоем мусора. Если вы выполняете много операций чтения, вам нужен высокопроизводительный класс буферизации, да. - person Dov; 14.12.2010