2009-12-07 1 views
18

Nella maggior parte dei sistemi operativi conformi a Unix e Posix, l'esecuzione di una chiamata del sistema operativo open() con O_APPEND indica al sistema operativo che le operazioni di scrittura atomica di accodamento e scrittura devono essere eseguite. Con questo comportamento, per i filesystem locali quando si scrive, si sa che viene aggiunto alla fine del file.Come posso eseguire una scrittura/aggiunta atomica in C#, o come posso ottenere i file aperti con il flag FILE_APPEND_DATA?

I sistemi operativi Windows supportano la stessa funzionalità passando FILE_APPEND_DATA nel parametro appropriato alla chiamata di sistema Win32 CreateFile().

riferimenti:

http://www.google.com/search?q=msdn+createfile 
or: http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx 

http://www.google.com/search?q=msdn+IoCreateFileSpecifyDeviceObjectHint 
or: http://www.google.com/search?q=msdn+IoCreateFileSpecifyDeviceObjectHint 

mio problema è questo, non è possibile determinare come ottenere questo comportamento in C# utilizzando .NET Framework Biblioteche, c'è un modo per ottenere tale comportamento con il Net Framework? Non credo che l'uso di FileMode.Append dia un comportamento del genere, tra l'altro.

risposta

30

Utilizzare uno degli overload del costruttore FileStream:

new FileStream(FileName, FileMode.Open, FileSystemRights.AppendData, 
      FileShare.Write, 4096, FileOptions.None) 

FileSystemRights.AppendData corrisponde con FILE_APPEND_DATA

FileStream sembra insistere sul buffer, in modo da assicurarsi il buffer è abbastanza grande per ogni scrittura e la chiamata Flush() dopo ogni scrittura.

piccolo esempio:

private void button1_Click(object sender, EventArgs e) { 
     Thread t1 = new Thread(DoIt); 
     Thread t2 = new Thread(DoIt); 
     t1.Start("a"); 
     t2.Start("b"); 
     Thread.Sleep(2000); 
     Environment.Exit(0); 
    } 

    private void DoIt(object p) { 
     using (FileStream fs = new FileStream(FileName, FileMode.Open, FileSystemRights.AppendData, 
      FileShare.Write, 4096, FileOptions.None)) { 
      using (StreamWriter writer = new StreamWriter(fs)) { 
       writer.AutoFlush = true; 
       for (int i = 0; i < 20; ++i) 
        writer.WriteLine("{0}: {1:D3} {2:o} hello", p, i, DateTime.Now); 
      } 
     } 
    } 
+0

Fred, questa è una risposta fantastica. – Cameron

+0

È come utilizzare l'API 'File.AppendText'? – Ben

+0

L'ultimo parametro del costruttore FileStream, 'bufferSize' o 4096 in questo esempio sarà il limite superiore della lunghezza di una scrittura atomica. – Cameron

-1

Perché non si può utilizzare

System.IO.File.AppendAllText("C:\\somefile.txt", "some content"); 

? Questa è una chiamata thread-safe/"atomic" pure.

+5

Questo purtroppo non dà l'operazione atomica processo-saggio che sto cercando. – Cameron