22 Stimmen

Wie kann ich ein atomares Schreiben/Anhängen in C# durchführen, oder wie bekomme ich Dateien mit dem FILE_APPEND_DATA-Flag geöffnet?

Unter den meisten Unix- und Posix-konformen Betriebssystemen zeigt die Ausführung eines open()-Betriebssystemaufrufs mit O_APPEND dem Betriebssystem an, dass Schreibvorgänge atomare Anhänge- und Schreibvorgänge sein sollen. Mit diesem Verhalten weiß man bei lokalen Dateisystemen, wenn man einen Schreibvorgang durchführt, dass dieser an das Ende der Datei angehängt wird.

Die Windows-Betriebssysteme unterstützen die gleiche Funktionalität durch die Übergabe von FILE_APPEND_DATA im entsprechenden Parameter des Win32 CreateFile()-Systemaufrufs.

Referenzen:

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

Mein Problem ist dies, ich kann nicht feststellen, wie man dieses Verhalten unter C# mit dem Net Framework erhalten Bibliotheken, gibt es eine Möglichkeit, ein solches Verhalten mit dem Net Framework zu erhalten? Ich glaube nicht, mit FileMode.Append gibt ein solches Verhalten, durch die Art und Weise.

40voto

Fred Mol Punkte 611

Verwenden Sie eine der Überladungen der Methode FileStream Konstrukteur:

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

FileSystemRights.AppendData entspricht FILE_APPEND_DATA

FileStream scheint auf Pufferung zu bestehen, also stellen Sie sicher, dass der Puffer groß genug ist für jede schreiben und rufen Sie Flush() nach jedem Schreibvorgang.

Kleines Beispiel:

    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);
            }
        }
    }

1voto

Giorgi Punkte 29625

Sie können anrufen CreateFile mit PInvoke mit den erforderlichen Parametern und übergeben Sie das resultierende Handle an eine der FileStream-Konstrukteure die SafeFileHandle als Parameter benötigt.

-3voto

enderminh Punkte 146

Warum können Sie nicht die

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

? Auch das ist ein thread-sicherer/"atomarer" Aufruf.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X