2009-12-07 9 views
18

atom append olmak ve yazma işlemleri için vardır. Bu davranışla, bir dosya yazarken yerel dosya sistemleri için dosyanın sonuna eklendiğini biliyorsunuzdur.C# ile atomik bir yazma/ekleme yapabilirim veya FILE_APPEND_DATA bayrağıyla nasıl dosya açabilirim? Olmaması için O_APPEND yazıyor OS gösterir ile bir açık() işletim sistemi çağrısı gerçekleştirerek işletim sistemlerini uygun çoğu Unixlerde ve Posix Altında

Windows işletim sistemleri, FILE_APPEND_DATA uygun parametresinde Win32 CreateFile() sistem çağrısına geçirilerek aynı işlevselliği destekler.

referanslar:

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 

Benim sorun budur, ben Net Framework kullanarak bu tür bir davranış almanın bir yolu yoktur, Net Framework kitaplıkları kullanarak C# altında bu davranışı nasıl tespit edemez? Bu arada, FileMode.Append kullanarak bu tür davranışlar verdiğine inanmıyorum.

cevap

30

birini kullanın:

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

FileSystemRights.AppendData

FileStream arabelleğe ısrar, bu yüzden yapmak gibi görünüyor FILE_APPEND_DATA karşılık gelen emin tampon her yazma ve çağrı için yeterince büyük Her yazmadan sonra Flush().

Minik örnek:

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, bu harika bir cevap. – Cameron

+0

'File.AppendText' API'sini kullanmakla aynı mıdır? – Ben

+0

Bu örnekte FileStream yapıcısı, 'bufferSize' veya 4096'nın son parametresi, bir atom yazısının uzunluğunun üst sınırı olacaktır. – Cameron

-1

Neden

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

kullanamıyorum? Bu da bir thread-safe/"atomik" çağrısı.

+5

Bu maalesef ben arıyorum süreç bilge atom operasyon vermez. – Cameron

1

CreateFile numaralı telefonu PInvoke numaralı telefonu kullanarak istediğiniz parametreleri girebilir ve sonuçta ortaya çıkan tutamacı, SafeFileHandle parametresini parametre olarak alan FileStream Constructors'dan birine iletebilirsiniz. FileStream yapıcısının aşırı yük