Domanda

L'articolo di Tim Bray "Salvataggio dei dati in modo sicuro" mi ha lasciato con domande aperte. Oggi, è più di un mese e non ho visto alcun follow-up su di esso, così ho deciso di affrontare il tema qui.

Un punto di questo articolo è che FileDescriptor.sync () dovrebbe essere chiamato ad essere sul sicuro quando si utilizza FileOutputStream. In un primo momento, ero molto irritato, perché non ho mai visto alcun codice Java facendo una sincronizzazione nel corso dei 12 anni che faccio Java. Tanto più che affrontare con i file è una cosa piuttosto semplice. Inoltre, il livello di JavaDoc FileOutputStream mai accennato alla sincronizzazione (Java 1,0-6). Dopo alcune ricerche, ho pensato ext4 potrebbe in realtà essere il primo file system corrente principale che richiede la sincronizzazione. (Ci sono altri file system in cui è consigliato sincronizzazione esplicita?)

I apprezzare alcune riflessioni generali in materia, ma ho anche alcune domande specifiche:

  1. Quando sarà Android fare la sincronizzazione al file system? Questo potrebbe essere periodica e inoltre in base agli eventi del ciclo di vita (per esempio processo di un'applicazione va al fondo).
  2. non FileDescriptor.sync () prendersi cura di sincronizzare i metadati? Che è la sincronizzazione della directory del file modificato. Confronta FileChannel.force ().
  3. Di solito, uno non scrive direttamente nel FileOutputStream. Ecco la mia soluzione (sei d'accordo?):
    FileOutputStream fileOut = ctx.openFileOutput(file, Context.MODE_PRIVATE);
    BufferedOutputStream out = new BufferedOutputStream(fileOut);
    try {
        out.write(something);
        out.flush();
        fileOut.getFD().sync();
    } finally {
        out.close();
    }
    
È stato utile?

Soluzione

Android farà la sincronizzazione quando è necessario -. Come quando lo schermo si spegne, lo spegnimento del dispositivo, ecc Se siete solo in cerca al funzionamento "normale", la sincronizzazione esplicita da applicazioni non è mai necessario

Il problema nasce quando l'utente estrae la batteria del proprio dispositivo (o fa un hard reset del kernel), e si desidera per essere sicuri di non perdere alcun dato.

Quindi, la prima cosa da realizzare:. Il problema è quando l'alimentazione è improvvisamente perso, quindi un arresto pulito non può accadere, e la questione di ciò che sta per accadere in memoria persistente, a quel punto

Se sono solo scrivendo un unico nuovo file indipendente, non importa quello che fai. L'utente potrebbe avere tirato la batteria mentre eri in mezzo della scrittura, proprio prima di iniziare a scrivere, ecc Se non la sincronizzazione, significa solo c'è qualche tempo dal momento in cui si sta scrivendo fatto durante il quale la batteria di trazione perderà i dati.

La grande preoccupazione qui è quando si vuole aggiornare un file. In tal caso, la prossima volta che leggete il file che si desidera avere o precedente contenuto, o nuovo Contenuti. Se non si desidera ottenere qualcosa a metà strada scritto, o perdere i dati.

Questo è spesso fatto scrivendo i dati in un nuovo file, e poi passare a quella dal vecchio file. Prima di EXT4 si sapeva che, una volta che aveva finito di scrivere un file, ulteriori operazioni su altri file non sarebbe andato sul disco fino a quando quelli sul quel file, così si potrebbe eliminare il file precedente o altrimenti fare operazioni che dipendono dal vostro nuovo file pienamente scritta.

Comunque ora se si scrive il nuovo file, quindi eliminare il vecchio, e la batteria è tirato, la prossima volta che avvio è possibile vedere che il vecchio file viene eliminato e nuovo file creato, ma i contenuti del nuovo file non è completare. Facendo la sincronizzazione, si assicura che il nuovo file è completamente scritto in quel punto così può fare ulteriori modifiche (ad esempio eliminando il vecchio file) che dipendono da quello stato.

Altri suggerimenti

fileOut.getFD().sync(); dovrebbe essere sulla clausola finally, prima della close().

sync() è il modo più importante di close() durata considerando.

Quindi, ogni volta che si vuole 'finitura' a lavorare su un file si dovrebbe sync() prima close()ing esso.

POSIX non garantisce che le scritture in sospeso saranno scritti su disco quando si emette un close().

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top