Поддержка больших файлов в C ++ - PullRequest
7 голосов
/ 08 июня 2009

64-битный API файла различен для каждой платформы.

в окнах: _fseeki64
в Linux: fseeko
в freebsd: еще один похожий вызов ...

Как наиболее эффективно сделать его более удобным и портативным? Есть ли полезные примеры?

Ответы [ 5 ]

14 голосов
/ 08 июня 2009

Большинство платформ на основе POSIX поддерживают символ препроцессора " _FILE_OFFSET_BITS ". Установка этого значения на 64 приведет к тому, что тип off_t будет 64 бит вместо 32, а функции манипулирования файлами, такие как lseek () будут автоматически поддерживать смещение 64 бит через некоторую магию препроцессора. С точки зрения времени компиляции добавление поддержки смещения 64-битного файла таким способом довольно прозрачно, если вы правильно используете соответствующие typedefs. Естественно, ваш ABI изменится, если вы выставите интерфейсы, которые используют тип off_t . В идеале вы должны определить это в командной строке, например ::

cxx -D_FILE_OFFSET_BITS=64

, чтобы убедиться, что он применяется ко всем заголовкам ОС, включенным в ваш код.

К сожалению, Windows не поддерживает этот символ препроцессора, поэтому вам придется либо обрабатывать его самостоятельно, либо полагаться на библиотеку, которая обеспечивает межплатформенную поддержку больших файлов. ACE - одна из таких библиотек (как на платформе POSIX, так и на платформах Windows - просто определите _FILE_OFFSET_BITS = 64 в обоих случаях). Я знаю, что Boost.filesystem также поддерживает большие файлы на платформах на основе POSIX, но я не уверен насчет Windows. Другие кроссплатформенные библиотеки, вероятно, предоставляют аналогичную поддержку.

2 голосов
/ 08 июня 2009

Мое лучшее предложение - использовать библиотеку для обработки этого, который уже существует.

Хорошим кандидатом может быть использование библиотеки файлов CPL из GDAL . Это обеспечивает межплатформенную поддержку больших файлов для чтения + записи, в ascii и двоичном доступе. Большинство форматов файлов GDAL были реализованы с его использованием и широко используются.

0 голосов
/ 08 июня 2009

Напишите класс, который инкапсулирует обработку файлов, и используйте условную компиляцию в классе для обработки каждой платформы.

Тогда просто используйте класс вместо собственной обработки файлов, когда вам нужен доступ к файлу из вашей программы.

Насколько я могу судить, не существует набора универсально переносимых функций ввода / вывода файлов, когда речь идет об обработке больших файлов.

0 голосов
/ 08 июня 2009

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

В любом случае, он предоставлял интерфейс, похожий на FILE, и работал довольно хорошо. Когда мне приходилось портировать на Windows, было легко включить соответствующую 64-битную поддержку. В Unix _FILE_OFFSET_BITS предоставляют достаточно магии, чтобы мне не пришлось играть слишком много игр, чтобы она работала.

0 голосов
/ 08 июня 2009

STLport имеет встроенную поддержку размера файла 64 бита. С другой стороны, если вы осуществляете интенсивный доступ к диску, вы можете использовать отображение файлов: mmap в unix и CreateFileMapping в Windows.

...