2011-01-30 12 views
11

Manejo de archivos binarios muy grandes (varios GB a múltiples TB por archivo). Estos archivos existen en un formato heredado y la actualización requiere escribir un encabezado en el FRENTE del archivo. Puedo crear un nuevo archivo y reescribir los datos, pero a veces esto puede llevar mucho tiempo. Me pregunto si hay alguna forma más rápida de lograr esta actualización. La plataforma está limitada a Linux y estoy dispuesto a usar funciones de bajo nivel (ASM, C, C++)/trucos del sistema de archivos para que esto suceda. La biblioteca primitiva es Java y JNI es completamente aceptable.¿Es posible anteponer datos a un archivo sin reescribir?

+0

Todas las respuestas confirmaron lo que ya sabía. Solo esperaba que hubiera algo mágico del que no tenía conocimiento. Gracias por el poder cerebral extra. – basszero

Respuesta

9

No hay una manera general de hacerlo de forma nativa.

Quizás algunos sistemas de archivos brinden algunas funciones para hacer esto (no se puede dar ninguna pista al respecto), pero su código dependerá del sistema de archivos.


Una solución podría ser la de simulando un sistema de archivos: se podría almacenar sus datos en un conjunto de varios archivos, y luego ofrecer algunas funciones para abrir, leer y escribir los datos como si se tratara de una fila india.

+0

+1 Usando la solución propuesta, el encabezado podría existir como un archivo al lado del archivo heredado, con un sufijo o extensión diferente. Si un archivo que se va a abrir se detecta como un archivo heredado, la abstracción del sistema de archivos accederá automáticamente al archivo de encabezado. –

+0

Marcando esto como correcto. Debe haber sospechas confirmadas. – basszero

0

Solo usaría las herramientas estándar de Linux para hacerlo.
Escribir otra aplicación para hacerlo parece que no sería óptimo.

cat headerFile oldFile > tmpFile && mv tmpFile oldFile 
+0

Creo que OP está buscando algo que no requiera reescribir el archivo completo (al igual que no sería necesario reescribirlo para agregar algunos datos). Si 'headerFile' es 1 byte, y' oldFile' es 10GB su comando tomará mucho tiempo. – peoro

+0

@ peoro: me doy cuenta de que esto es lo que quiere el OP. Pero para que FS sea generalmente eficiente, no funcionan así. Como compensación de diseño, son muy eficientes para funciones comunes, pero como resultado son ineficientes para operaciones menos comunes. –

4

Suena loco, pero puede almacenar los datos del archivo en orden inverso, si es posible cambiar la función que lee los datos del archivo. En ese caso, puede anexar datos (en orden inverso) al final del archivo. Es solo una idea general, así que no puedo recomendar nada en particular. El código para revertir de archivo lata actual es el siguiente:

std::string records; 
ofstream out; 
std::copy(records.rbegin(), records.rend(), std::ostream_iterator<string>(out)); 
+0

Buena idea pero eso requeriría revertir la escritura inicial del archivo (y también anexa). Entonces, la idea solo es posible con los archivos existentes, e incluso entonces se requiere una reescritura completa (en orden inverso). –

+0

+1 para pensar fuera de la caja – sleske

2

Depende de lo que quiere decir con "trucos" del sistema de archivos. Si está dispuesto a ensuciarse con el formato en disco del sistema de archivos, y, el tamaño del encabezado que desea agregar es un múltiplo del tamaño del bloque del sistema de archivos, entonces podría escribir un programa para manipular directamente las estructuras en el disco del sistema de archivos (con el sistema de archivos desmontado).

Esta empresa es tan peluda como suena, aunque solo valdría la pena si tienes que procesar cientos de estos archivos gigantes.

0

Sé que esta es una vieja pregunta, pero espero que esto ayude a alguien en el futuro. Al igual que en simulando un sistema de archivos, puede simplemente usar una tubería con nombre:

mkfifo /path/to/file_to_be_read 
{ echo "HEADER"; cat /path/to/source_file; } > /path/to/file_to_be_read 

A continuación, ejecutar el programa de herencia contra /path/to/file_to_be_read, y la entrada sería:

HEADER 
contents of /path/to/source_file 
... 

Esto funcionará siempre que el programa lea el archivo secuencialmente y no haga mmap() o rewind() pasando el búfer.

Cuestiones relacionadas