Come posso fare una scrittura atomica / accodare in C #, o come faccio a ottenere i file aperti con la bandiera FILE_APPEND_DATA?

StackOverflow https://stackoverflow.com/questions/1862309

  •  16-09-2019
  •  | 
  •  

Domanda

In molti Unix e Posix conformi sistemi operativi che eseguono un () chiamata di sistema operativo aperto con l'O_APPEND indica al sistema operativo che scrive devono essere accodamento atomico e scrittura. Con questo comportamento, per i file system locali quando si esegue una scrittura, si sa che ottiene aggiunto alla fine del file.

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

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

Il mio problema è questo, non posso determinare come ottenere questo comportamento in C # utilizzando il Net Framework Biblioteche, c'è un modo per ottenere tale comportamento con il Net Framework? Non credo usando FileMode.APPEND dà tale comportamento, tra l'altro.

È stato utile?

Soluzione

Utilizzare uno degli overload del costruttore FileStream:

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

FileSystemRights.AppendData corrisponde FILE_APPEND_DATA

FileStream sembra insistere sul buffer, in modo da assicurarsi il buffer è abbastanza grande per ogni scrivere e chiamare 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);
            }
        }
    }

Altri suggerimenti

È possibile chiamare CreateFile usando < a href = "http://www.pinvoke.net/default.aspx/kernel32/CreateFile.html" rel = "nofollow"> PInvoke con i parametri richiesti e passare la maniglia conseguente ad uno dei FileStream Costruttori che prende SafeFileHandle come parametro.

Perché non si può usare

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

? Questo è un thread-safe / "atomica" chiamata pure.

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