Domanda

Ok, per spiegare; Sto sviluppando per un sistema che può subire un'interruzione di corrente in qualsiasi momento, un punto che sto testando è direttamente dopo aver scritto un file usando uno StreamWriter. Il codice seguente:

// Write the updated file back out to the Shell directory.
using (StreamWriter shellConfigWriter =
        new StreamWriter(@"D:\xxx\Shell\Config\Game.cfg.bak"))
{
    for (int i = 0; i < configContents.Count; i++)
    {
        shellConfigWriter.WriteLine(configContents[i]);
    }
    shellConfigWriter.Close();
}

FileInfo gameCfgBackup = new FileInfo(@"D:\xxx\Shell\Config\Game.cfg.bak");
gameCfgBackup.CopyTo(@"D:\xxx\Shell\Config\Game.cfg", true);

Scrive il contenuto di shellConfigWriter (un Elenco di stringhe) in un file usato come archivio temporaneo, quindi viene copiato sull'originale. Ora, dopo che questo codice ha terminato l'esecuzione, la potenza viene persa, al riavvio il file Game.cfg esiste ed ha le dimensioni corrette, ma è completamente vuoto. Inizialmente pensavo che ciò fosse dovuto al fatto che Write-Caching fosse abilitato sul disco rigido, ma anche senza esso si verifica ancora (anche se meno spesso).

Qualsiasi idea sarebbe molto gradita!

Aggiorna: Ok, quindi dopo aver rimosso le istruzioni .Close () e aver chiamato .Flush () dopo ogni operazione di scrittura i file continuano a finire in bianco. Potrei fare un ulteriore passo avanti e creare prima un backup del file originale, prima di crearne uno nuovo, quindi ho abbastanza backup per fare un controllo di integrità, ma non credo che aiuterà a risolvere il problema sottostante ( che quando gli dico di scrivere, svuota e chiudi un file ... Non lo fa!).

È stato utile?

Soluzione

Impedisci al sistema operativo di bufferizzare l'output usando il parametro FileOptions del costruttore dell'oggetto FileStream :

    using (Stream fs = new FileStream(@"D:\xxx\Shell\Config\Game.cfg.bak", FileMode.Create, FileAccess.Write, FileShare.None, 0x1000, FileOptions.WriteThrough))
    using (StreamWriter shellConfigWriter = new StreamWriter(fs))
    {
        for (int i = 0; i < configContents.Count; i++)
        {
            shellConfigWriter.WriteLine(configContents[i]);
        }
        shellConfigWriter.Flush();
        shellConfigWriter.BaseStream.Flush();
    }

Altri suggerimenti

Prima di tutto, non è necessario chiamare shellConfigWriter.Close () lì. L'istruzione using se ne occuperà. Quello che potresti voler fare invece per evitare interruzioni di corrente è chiamare shellConfigWriter.Flush () .


Aggiorna
Qualcos'altro che dovresti considerare è che se un'interruzione di corrente può davvero accadere in qualsiasi momento, potrebbe accadere nel mezzo di una scrittura, in modo tale che solo alcuni byte passino a un file. Non c'è davvero modo di fermarlo.

Per proteggersi da questi scenari, una procedura comune è quella di utilizzare i file flag di stato / condizione. Usi l'esistenza o la non esistenza sul file system di un file a zero byte con un nome particolare per dire al tuo programma dove riprendere nuovamente quando riprende. Quindi non crei o distruggi i file che attivano uno stato particolare fino a quando non sei sicuro che hai raggiunto quello stato e completato il precedente.

Il rovescio della medaglia qui è che potrebbe significare buttare via molto lavoro di tanto in tanto. Ma il vantaggio è che significa che la parte funzionale del tuo codice sembra normale: c'è poco lavoro extra da fare per rendere il sistema sufficientemente robusto.

Desideri impostare AutoFlush = true;

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