C'è una regione nel file (possibile piccola) che desidero sovrascrivere. Suppongo che chiami fseek, fwrite, fsync. Esiste un modo per garantire l'atomicità di tale operazione di riscrittura delle regioni, ad es. Ho bisogno di essere sicuro, che in ogni caso di fallimento la regione conterrà solo vecchi dati (prima della modifica), o solo nuovi (modificati) dati, ma non un mix di questo.Modifica file atomico
Ci sono due cose che voglio evidenziare.
Prima: E 'ok se non v'è alcun modo per scrivere atomicamente qualsiasi regione dimensioni - siamo in grado di gestirlo aggiungendo dati al file, fsync'ing, e poi riscrivere 'puntatore' zona nel file, poi di nuovo fsyncing . Tuttavia, se la scrittura "pointer" non è atomica, possiamo comunque avere file corrotti con puntatori illegali.
Secondo: Sono sicuro che scrivere regioni di 1 byte è atomico: non vedrò nel file alcun byte che non ho mai inserito. Quindi possiamo usare alcuni trucchi con l'allocazione di due regioni per gli indirizzi e utilizzare lo switch da 1 byte, quindi riscrivere la regione è diventato - aggiungere nuovi dati, sincronizzare, riscrivere uno dei due (non utilizzati) slot del puntatore, sincronizzare di nuovo e quindi riscrivere 'switch byte 'e di nuovo sincronizzato. Quindi l'operazione di sovrascrittura ora contiene almeno 3 invocazioni fsync.
Tutto questo sarebbe molto più semplice, se avrò la scrittura atomica per i lunghi, ma ce l'ho davvero?
C'è un modo per gestire questa situazione senza utilizzare il metodo, di cui al punto 2?
Un'altra domanda è: c'è qualche garanzia di ordine tra scrittura e sincronizzazione? Ad esempio, se chiamo fseek, fwrite [1], fseek, fwrite [2], fsync, posso scrivere a [2] commited, e scrivere a [1] - not commit?
Questa domanda è applicabile al sistema operativo linux e windows, qualsiasi risposta particolare (ad esempio in Ubuntu versione a.b.c ....) è anche desiderata.
[fsync] (http://linux.die.net/man/3/fsync) sembra essere abbastanza implementazione/filesystem dipendente. http://blogs.gnome.org/alexl/2009/03/16/ext4-vs-fsync-my-take/ – zapl
Quello di cui parli è noto come "controllo del commit" o "commit/rollback", o "transazioni". –
(L'unico modo (quasi) completamente affidabile di fare ciò che vuoi, in assenza di una funzione di elaborazione delle transazioni sulla scatola, è quello di fare il vecchio scambio di file: copia il vecchio file in nuovo, cambia nuovo, rinomina nuovo per sostituire vecchio.) –