2011-01-30 7 views
11

Mi occupo di file binari molto grandi (diversi GB in più TB per file). Questi file esistono in un formato legacy e l'aggiornamento richiede la scrittura di un'intestazione sul FRONT del file. Posso creare un nuovo file e riscrivere i dati, ma a volte questo può richiedere molto tempo. Mi chiedo se ci sia un modo più veloce per realizzare questo aggiornamento. La piattaforma è limitata a Linux e sono disposto a utilizzare le funzioni di basso livello (ASM, C, C++)/trucchi del file system per farlo accadere. La libreria primitiva è Java e JNI è completamente accettabile.È possibile anteporre dati a un file senza riscrivere?

+0

Tutte le risposte hanno confermato ciò che già sapevo. Speravo solo che ci fosse della magia di cui non ero a conoscenza. Grazie per il potere extra del cervello. – basszero

risposta

9

Non c'è un modo generale per farlo in modo nativo.

Forse alcuni sistemi di file forniscono alcune funzioni per eseguire questa operazione (non è possibile fornire alcun suggerimento a riguardo), ma il codice sarà quindi dipendente dal file system.


Una soluzione potrebbe essere quella di simulando un file-system: è possibile memorizzare i dati su una serie di diversi file, e quindi fornire alcune funzioni per aprire, leggere e scrivere i dati come se si trattasse di un file singolo.

+0

+1 Utilizzando la soluzione proposta, l'intestazione potrebbe esistere come file accanto al file legacy, con un suffisso o un'estensione diversi. Se un file da aprire viene rilevato come file legacy, l'astrazione del file system accederà automaticamente al file di intestazione. –

+0

Contrassegnare come corretto. I sospetti sono stati confermati. – basszero

0

Vorrei solo usare gli strumenti standard di Linux per farlo.
Scrivere un'altra applicazione per farlo sembra non ottimale.

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

Penso che OP stia cercando qualcosa che non richieda la riscrittura dell'intero file (proprio come se non fosse necessario riscriverlo per aggiungere alcuni dati). Se 'headerFile' è 1 byte e' oldFile' è 10GB il tuo comando impiegherà molto tempo. – peoro

+0

@peoro: mi rendo conto che questo è ciò che l'OP vuole. Ma per rendere le FS generalmente efficienti non funzionano così. Essendo un trade design off sono molto efficienti per le funzioni comuni, ma di conseguenza sono inefficienti per operazioni meno comuni. –

4

sembra folle, ma è possibile memorizzare i dati del file in ordine inverso, se è possibile cambiare la funzione che legge i dati dal file. In tal caso è possibile aggiungere dati (in ordine inverso) alla fine del file. È solo un'idea generale, quindi non posso raccomandare nulla di particolare. Il codice per l'inversione del can file corrente si presenta così:

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

Bella idea ma che richiederebbe l'inversione della scrittura iniziale dei file (e anche degli allegati). Quindi l'idea è possibile solo con i file esistenti, e anche allora è necessario completare la riscrittura (in ordine inverso). –

+0

+1 per pensare fuori dagli schemi – sleske

2

Dipende da cosa si intende per "trucchi" del file system. Se sei disposto a fare i conti con il formato su disco del file system, e, la dimensione dell'intestazione che desideri aggiungere è un multiplo della dimensione del blocco del filesystem, quindi potresti scrivere un programma per manipolare direttamente le strutture su disco del file system (con il filesystem non montato).

Questa azienda è tanto pelosa come sembra, ma probabilmente ne varrà la pena se si disporrà di centinaia di questi file giganti da elaborare.

0

So che questa è una vecchia domanda, ma spero che questo aiuti qualcuno in futuro. Simile a simulando un filesystem, si può semplicemente utilizzare un named pipe:

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

Quindi, si esegue il programma legacy contro /path/to/file_to_be_read, e l'ingresso sarebbe:

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

Ciò funzionerà come Finché il programma legge il file in sequenza e non esegue mmap() o rewind() oltre il buffer.