Buscando y leyendo archivos grandes en una aplicación Linux C ++

Estoy corriendo en un desbordamiento de enteros usando las opciones ftell y fseek estándar dentro de G ++, pero creo que estaba equivocado porque parece que ftell64 y fseek64 no están disponibles. He estado buscando y muchos sitios web parecen hacer referencia al uso de lseek con el tipo de datos off64_t , pero no he encontrado ningún ejemplo que haga referencia a algo igual a fseek . En este momento, los archivos en los que estoy leyendo son archivos CSV de 16GB con la expectativa de al menos duplicarlos.

Sin ninguna biblioteca externa, ¿cuál es el método más directo para lograr una estructura similar a la del par fseek / ftell ? Mi aplicación ahora funciona usando las bibliotecas GCC / G ++ estándar para 4.x.

fseek64 es una función C. Para que esté disponible, deberá definir _FILE_OFFSET_BITS = 64 antes de incluir los encabezados del sistema. Eso más o menos definirá fseek como fseek64. O hazlo en los argumentos del comstackdor, por ejemplo, gcc -D_FILE_OFFSET_BITS = 64 ….

http://www.suse.de/~aj/linux_lfs.html tiene una excelente visión de soporte de archivos grandes en Linux:

  • Comstack tus progtwigs con “gcc -D_FILE_OFFSET_BITS = 64”. Esto obliga a todas las llamadas de acceso a archivos a usar las variantes de 64 bits. Varios tipos también cambian, por ejemplo off_t se convierte en off64_t. Por lo tanto, es importante usar siempre los tipos correctos y no usar, por ejemplo, int en lugar de off_t. Para portabilidad con otras plataformas, debe usar getconf LFS_CFLAGS que devolverá -D_FILE_OFFSET_BITS = 64 en plataformas Linux, pero puede devolver algo más, por ejemplo, Solaris. Para vincular, debe usar los indicadores de enlace que se informan a través de getconf LFS_LDFLAGS. En sistemas Linux, no necesita banderas de enlace especiales.
  • Defina _LARGEFILE_SOURCE y _LARGEFILE64_SOURCE. Con estos define, puede usar las funciones LFS como open64 directamente.
  • Utilice el indicador O_LARGEFILE con abierto para operar en archivos grandes.

Si desea apegarse a las interfaces estándar ISO C, use fgetpos() y fsetpos() . Sin embargo, estas funciones solo son útiles para guardar una posición de archivo y volver a la misma posición más adelante. Representan la posición utilizando el tipo fpos_t , que no es obligatorio que sea un tipo de datos entero. Por ejemplo, en un sistema basado en registros, podría ser una estructura que contiene un número de registro y un desplazamiento dentro del registro. Esto puede ser muy limitante.

POSIX define las funciones ftello() y fseeko() , que representan la posición utilizando el tipo off_t . Se requiere que sea un tipo entero, y el valor es un desplazamiento de bytes desde el comienzo del archivo. Puede realizar operaciones aritméticas y puede usar fseeko() para realizar búsquedas relativas. Esto funcionará en Linux y otros sistemas POSIX.

Además, compile con -D_FILE_OFFSET_BITS=64 (Linux / Solaris). Esto definirá off_t como un tipo de 64 bits (es decir, off64_t ) en lugar de long , y redefinirá las funciones que usan compensaciones de archivos para que sean las versiones que toman compensaciones de 64 bits. Este es el valor predeterminado cuando comstack para 64 bits, por lo que no es necesario en ese caso.

fseek64() no es estándar, los documentos del comstackdor deberían decirle dónde encontrarlo.

¿Has probado fgetpos y fsetpos ? Están diseñados para archivos grandes y la implementación generalmente usa un tipo de 64 bits como base para fpos_t.

¿Has probado fseeko () con el símbolo del preprocesador _FILE_OFFSET_BITS establecido en 64 ?

Esto le dará una interfaz similar a fseek () pero con un parámetro offset de tipo off_t en lugar de long . Establecer _FILE_OFFSET_BITS = 64 hará que off_t sea un tipo de 64 bits.

Lo mismo para va para ftello () .

Usa fsetpos(3) y fgetpos(3) . Usan el tipo de datos fpos_t , que creo que puede contener al menos 64 bits.