2009-12-07 7 views
18

Theo hầu hết các hệ điều hành Unix và Posix phù hợp thực hiện cuộc gọi hệ điều hành mở() với O_APPEND cho biết hệ điều hành viết là các hoạt động nối và ghi nguyên tử. Với hành vi này, đối với các hệ thống tệp cục bộ khi bạn viết, bạn biết nó được nối vào cuối tệp.Làm cách nào để viết/thêm nguyên tử trong C# hoặc làm cách nào để nhận tệp được mở bằng cờ FILE_APPEND_DATA?

Hệ điều hành Windows hỗ trợ chức năng tương tự bằng cách chuyển FILE_APPEND_DATA trong thông số thích hợp cho cuộc gọi hệ thống Win32 CreateFile().

tham khảo:

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 

Vấn đề của tôi là thế này, tôi không thể xác định làm thế nào để có được hành vi này trong môi trường C# sử dụng Net Framework Libraries, là có một cách để có được hành vi như vậy bằng cách sử dụng Net Framework? Tôi không tin rằng bằng cách sử dụng FileMode.Append cho hành vi như vậy, bằng cách này.

Trả lời

30

Sử dụng một trong những quá tải của các nhà xây dựng FileStream:

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

FileSystemRights.AppendData tương ứng với FILE_APPEND_DATA

FileStream dường như nhấn mạnh vào đệm, do đó hãy chắc chắn rằng bộ đệm đủ lớn cho mỗi ghi và cuộc gọi Flush() sau mỗi lần viết.

Tiny dụ:

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, đây là một câu trả lời tuyệt vời. – Cameron

+0

Giống như sử dụng API 'File.AppendText'? – Ben

+0

Tham số cuối cùng của hàm tạo FileStream, 'bufferSize', hoặc 4096 trong ví dụ này sẽ là một giới hạn trên trên chiều dài của một ghi nguyên tử. – Cameron

-1

Tại sao bạn không thể sử dụng

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

? Đó cũng là một cuộc gọi an toàn/"nguyên tử".

+5

này tiếc là không cung cấp cho các hoạt động nguyên tử quá trình khôn ngoan tôi đang tìm kiếm. – Cameron

1

Bạn có thể gọi CreateFile bằng cách sử dụng PInvoke với các tham số bắt buộc và chuyển điều khiển kết quả đến một trong số FileStream Constructors, tính năng này sẽ nhận tham số SafeFileHandle.