Вопрос по c, c++, linux – Поиск и чтение больших файлов в приложении Linux C ++

14

Я сталкиваюсь с целочисленным переполнением, используя стандартный Ftell а также FSEEK параметры внутри G ++, но я думаю, что я ошибся, потому что кажется, что Ftell64 а также Fseek64 недоступны. Я искал, и многие сайты ссылаются на Lseek с Off64_t datatype, но я не нашел примеров, ссылающихся на что-то равное FSEEK. Прямо сейчас файлы, в которых я читаю, представляют собой файлы объемом 16 ГБ + CSV, ожидая, по крайней мере, удвоения этог

Без каких-либо внешних библиотек, какой самый простой метод для достижения такой же структуры, как с FSEEK / ftell пара? Мое приложение сейчас работает с использованием стандартных библиотек GCC / G ++ для 4.x.

Ваш Ответ

5   ответов
27

вам нужно определить _FILE_OFFSET_BITS = 64, прежде чем включать системные заголовки, которые более или менее определят fseek как фактически fseek64. Или сделайте это в аргументах компилятора, например gcc -D_FILE_OFFSET_BITS = 64 ....

http: //www.suse.de/~aj/linux_lfs.htm имеет большую поддержку больших файлов в Linux:

Скомпилируйте ваши программы с помощью "gcc -D_FILE_OFFSET_BITS = 64". Это заставляет все вызовы доступа к файлу использовать 64-битные варианты. Меняются также несколько типов, например off_t становится off64_t. Поэтому важно всегда использовать правильные типы и не использовать, например, int вместо off_t. Для переносимости с другими платформами вы должны использовать getconf LFS_CFLAGS, который будет возвращать -D_FILE_OFFSET_BITS = 64 на платформах Linux, но может возвращать что-то другое, например, на. Solaris. Для связи вы должны использовать флаги связи, о которых сообщается через getconf LFS_LDFLAGS. В системах Linux вам не нужны специальные флаги ссылок.Define _LARGEFILE_SOURCE и _LARGEFILE64_SOURCE. С этими определениями вы можете напрямую использовать функции LFS, такие как open64. Используйте флаг O_LARGEFILE с открытым для работы с большими файлами.
Итак, я следовал твоим инструкциям и все компилирует файл. Но я, кажется, все еще получаю переполнение. Как бы вы использовали параметр O_LARGEFILE с fopen64? John Bellone
Я использую только C API и использую off64_t в качестве своих типов. John Bellone
Если вы компилируете с -D_FILE_OFFSET_BITS = 64, O_LARGEFILE предоставляется автоматически. Это не стандартный флаг; он используется в Linux для отслеживания того, был ли файл открыт с помощью больших файловых интерфейсов. mark4o
Вы задали вопрос как C ++, вы используете / смешиваете операции с файлами C с потоками C ++ или используете только API C? Кроме того, у вас есть тестовый код для воспроизведения поведения? Крайне важно, чтобы вы использовали правильные типы, имеющие дело с длинами / смещениями. nos
Ключ к этому ответу -D_FILE_OFFSET_BITS = 64, и именно это и решило мою проблему. При использовании нескольких общих библиотек я бы предложил применить это ко всем сборочным файлам сборки. John Bellone
10

используйтеfgetpos() а такжеfsetpos(). Однако эти функции полезны только для сохранения файловой позиции и возврата к той же позиции позже. Они представляют позицию, используя типfpos_t, который не обязательно должен быть целочисленным типом данных. Например, в системе на основе записей это может быть структура, содержащая номер записи и смещение в записи. Это может быть слишком ограничивающим.

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

Кроме того, скомпилируйте с-D_FILE_OFFSET_BITS=64 (Linux / Solaris). Это определитoff_t быть 64-битным типом (т. е.off64_t) вместо тогоlong, и переопределит функции, которые используют смещения файлов, чтобы быть версиями, которые принимают 64-битные смещения. Это значение по умолчанию при компиляции для 64-битной системы, поэтому в этом случае не требуется.

5

fseek64() не является стандартным, документы компилятора должны указать, где его найти.

Ты пыталсяfgetpos а такжеfsetpos? Они предназначены для больших файлов, и реализация обычно использует 64-битный тип в качестве основы для fpos_t.

5

fseeko () с _FILE_OFFSET_BITS символ препроцессора установлен на 64?

Это даст тебеfseek () -подобный интерфейс, но с параметром смещения типа Off_t вместо тогодлинна. Настройка _FILE_OFFSET_BITS = 64 сделаю Off_t 64-битный тип.

То же самое относится и кftello ().

2

fsetpos(3) а такжеfgetpos(3). Они используютfpos_t datatype, который, я уверен, может содержать как минимум 64 бита.

Похожие вопросы