Поиск и чтение больших файлов в приложении 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 бит.