Ошибка fread для больших файлов?

Мне нужно проанализировать файл размером 16 ГБ. Я читаю файл последовательно, используя fread() и fseek(). Возможно ли это? Подойдет ли fread() для такого большого файла?


person bcubed    schedule 29.09.2010    source источник
comment
Можете ли вы уточнить используемый язык?   -  person Gary Willoughby    schedule 30.09.2010
comment
Я собираюсь пойти дальше и угадать C   -  person wallacer    schedule 30.09.2010
comment
существуют ли вообще fread и fseek в качестве стандартов на другом языке?   -  person wallacer    schedule 30.09.2010


Ответы (5)


Вы не упомянули язык, поэтому я предполагаю C.

Я не вижу проблем с fread, но fseek и ftell могут возникнуть проблемы.

Эти функции используют long int в качестве типа данных для хранения позиции в файле, а не что-то разумное вроде fpos_t или даже size_t. Это означает, что они могут не работать с файлом размером более 2 ГБ и, безусловно, могут не работать с файлом размером 16 ГБ.

Вам нужно посмотреть, насколько велик long int на вашей платформе. Если это 64 бита, то все в порядке. Если это 32, у вас, вероятно, возникнут проблемы при использовании ftell для измерения расстояния от начала файла.

Попробуйте вместо этого использовать fgetpos и fsetpos.

person David Thornley    schedule 29.09.2010
comment
Комментарий ..вы не можете легально использовать ненулевые смещения fseek без вызова ftell верен только для файлов, открытых в текстовом режиме. Файлы, открытые в двоичном режиме, могут использовать SEEK_SET и SEEK_CUR с произвольным смещением. - person caf; 30.09.2010
comment
@caf: Спасибо. Мой ответ был изменен, как вы предложили. - person David Thornley; 30.09.2010

Спасибо за ответ. Я понял, где ошибся. fseek() и ftell() не работают с файлами размером более 4 ГБ. Я использовал _fseeki64() и _ftelli64(), и теперь все работает нормально.

person bcubed    schedule 29.09.2010

Если реализовано правильно, это не должно быть проблемой. Я предполагаю, что последовательно вы имеете в виду, что просматриваете файл отдельными фрагментами и перемещаете указатель файла.

Посетите http://www.computing.net/answers/programming/using-fread-with-a-large-file-/10254.html

Похоже, он делал почти то же самое, что и ты.

person wallacer    schedule 29.09.2010

Это зависит от того, что вы хотите сделать. Если вы хотите прочитать все 16 ГБ данных в памяти, есть вероятность, что вам не хватит памяти или места в куче приложения.

Скорее прочитайте фрагмент данных по фрагменту и выполните обработку этих фрагментов (и освободите ресурсы, когда закончите).

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

person Buhake Sindi    schedule 29.09.2010

Если вы работаете в POSIX-системе, вам нужно убедиться, что вы создали свою программу с поддержкой смещения 64-битного файла. POSIX предписывает (или, по крайней мере, разрешает, и большинство систем применяет это) реализацию запрещать операции ввода-вывода для файлов, размер которых не соответствует off_t, даже если единственный выполняемый ввод-вывод является последовательным без поиска.

В Linux это означает, что вам нужно использовать -D_FILE_OFFSET_BITS=64 в командной строке gcc.

person R.. GitHub STOP HELPING ICE    schedule 29.09.2010