Поиск и чтение больших файлов в приложении Linux С++

Я запускаю целочисленное переполнение, используя стандартные опции ftell и fseek внутри g++, но, я думаю, я ошибся, потому что кажется, что ftell64 и fseek64 недоступны. Я искал, и многие сайты, похоже, ссылаются на lseek с типом данных off64_t, но я не нашел примеров, ссылающихся на что-то равное fseek. Прямо сейчас файлы, которые я читаю, это 16GB + CSV файлы с ожиданием, по крайней мере, вдвое меньше.

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

Ответ 1

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

http://www.suse.de/~aj/linux_lfs.html имеет большой обход поддержки большого файла в 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 вам не нужны специальные флаги ссылок.
  • Определите _LARGEFILE_SOURCE и _LARGEFILE64_SOURCE. С помощью этих определений вы можете напрямую использовать функции LFS, такие как open64.
  • Используйте флаг O_LARGEFILE с открытым для работы с большими файлами.

Ответ 2

Если вы хотите придерживаться стандартных интерфейсов ISO C, используйте 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-разрядных, поэтому в этом случае не требуется.

Ответ 3

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

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

Ответ 4

Вы пробовали fseeko() с символом препроцессора _FILE_OFFSET_BITS, установленным для 64?

Это даст вам fseek() -подобный интерфейс, но со значением параметра offset off_t вместо long. Установка _FILE_OFFSET_BITS = 64 сделает off_t 64-разрядный тип.

То же самое для ftello().

Ответ 5

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