Как мога преносимо да включа поддръжката на големи файлове?

В момента пиша програма на C, която чете и записва файлове, които може да са с размер над 2 GiB. В Linux feature_test_macros(7) указва:

   _LARGEFILE64_SOURCE
          Expose definitions for the alternative API specified by the LFS (Large File Summit) as a  "tran‐
          sitional  extension"  to  the  Single  UNIX  Specification.  (See ⟨http://opengroup.org/platform
          /lfs.html⟩) The alternative API consists of a set of new objects  (i.e.,  functions  and  types)
          whose names are suffixed with "64" (e.g., off64_t versus off_t, lseek64() versus lseek(), etc.).
          New programs should not employ this interface; instead _FILE_OFFSET_BITS=64 should be employed.

   _FILE_OFFSET_BITS
          Defining this macro with the value 64 automatically converts references to 32-bit functions  and
          data  types related to file I/O and file system operations into references to their 64-bit coun‐
          terparts.  This is useful for performing I/O on large files (> 2 Gigabytes) on  32-bit  systems.
          (Defining  this macro permits correctly written programs to use large files with only a recompi‐
          lation being required.)  64-bit systems naturally permit file sizes greater  than  2  Gigabytes,
          and on those systems this macro has no effect.

Това гарантирано ли е преносимо?

Solaris предлага в lfcompile(5):

 Applications can be compiled in the large  file  compilation
 environment by using the following methods:

     o    Use the getconf(1) utility with one or more of  the
          arguments listed in the table below. This method is
          recommended for portable applications.

          ____________________________________________________________
         |     argument     |                 purpose                |
         |__________________|________________________________________|
         | LFS_CFLAGS       |  obtain compilation flags necessary  to|
         |                  |  enable   the  large  file  compilation|
         |                  |  environment                           |
         | LFS_LDFLAGS      |  obtain link editor options            |
         | LFS_LIBS         |  obtain link library names             |
         | LFS_LINTFLAGS    |  obtain lint options                   |
         |__________________|________________________________________|

     o    Set the compile-time flag _FILE_OFFSET_BITS  to  64
          before including any headers. Applications may com-
          bine objects produced in the large file compilation
          environment  with  objects  produced in the transi-
          tional compilation environment, but must be careful
          with  respect  to  interoperability  between  those
          objects. Applications  should  not  declare  global
          variables of types whose sizes change between  com-
          pilation environments.

Това преносимо ли е? На моята Linux машина предаването на тези ключове на getconf няма да изведе нищо. (Което означава, че ключовете съществуват).

Има ли някакъв преносим подход?


person fuz    schedule 17.08.2013    source източник
comment
Има ли останали машини, които не могат да обработват 2 GB файлове?   -  person Carl Norum    schedule 18.08.2013
comment
@CarlNorum Не става въпрос за машини, които не могат да се справят с тях. Дори при текущи i386 Linux, ако отворите() файл, който е по-голям от 4 GiB без O_LARGEFILE, получавате EOVERFLOW. Работата с големи файлове изисква да имате 64-битов тип данни. Тъй като някои помощни програми разчитат на 32-битови отмествания във файлове, трябва да включите поддръжката на големи файлове по време на компилация, преди да можете да използвате големи файлове.   -  person fuz    schedule 18.08.2013
comment
Веднъж демонстрирах проста програма за криптиране на файлове XOR, която написах. Помислих си защо да не криптирам този наистина голям филмов файл, който имам. Кратка история, демонстрацията не мина толкова добре. Бих искал да знам какви (ако има такива) преносими решения съществуват.   -  person recursion.ninja    schedule 18.08.2013
comment
@FUZxxl: Ако getconf не извежда нищо, това вероятно означава, че не се нуждаете от специални флагове за поддръжка на големи файлове - вероятно защото вашата среда е 64-битова.   -  person caf    schedule 18.08.2013


Отговори (1)


Използвайте confstr интерфейс или съответния getconf програма и опитайте различните опции _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS и т.н., докато намерите тази, която работи. Това ще ви даде CFLAGS, LDFLAGS и LIBS, необходими за подходяща среда.

person R.. GitHub STOP HELPING ICE    schedule 17.08.2013
comment
Намерете такъв, който работи, всъщност не звучи като преносим начин. Нямам на разположение всяка съществуваща Unix система и догадките няма да ми дадат сигурност. - person fuz; 18.08.2013
comment
Всъщност прочетохте ли връзките, които предоставих, които документират тези интерфейси? Всъщност така ги използвате. На всяка съответстваща система, ако има среда за компилиране с желаното свойство, че off_t е 64 бита, това ще го намери. Ако не, нямате късмет. - person R.. GitHub STOP HELPING ICE; 18.08.2013
comment
Да направих го. Тези документи дефинират конфигурационни ключове само за определени стойности на променлива ширина. Нито един от тези ключове не споменава поддръжка на големи файлове. Разбира се, бих могъл да предположа, че конфигурационният ключ за поддръжка на големи файлове, който съществува на Solaris, е преносим, ​​но това предположение не е подкрепено без документ, описващ, че това поведение е преносимо. - person fuz; 18.08.2013
comment
Съжалявам, че съм такъв тъпак. Бях просветлен. - person fuz; 18.07.2014
comment
Има ли начин да го направя на windows и на posix би било чудесно, ако не трябваше да посочвам версията на POSIX... - person MarcusJ; 02.10.2017