2013-02-02 35 views
19

Tôi gặp phải một điều thú vị khi sử dụng StreamWriter với FileStream để nối văn bản vào tệp hiện có trong .NET 4.5 (chưa thử bất kỳ khung cũ nào). Tôi đã thử hai cách, một người làm việc và một người thì không. Tôi tự hỏi sự khác biệt giữa hai cái là gì.Ghi vào tệp txt với StreamWriter và FileStream

Cả hai phương pháp chứa đoạn mã sau ở đầu

if (!File.Exists(filepath)) 
    using (File.Create(filepath)); 

Tôi có việc tạo ra trong một tuyên bố using vì tôi đã tìm thấy thông qua kinh nghiệm cá nhân mà đó là cách tốt nhất để đảm bảo rằng các ứng dụng đóng đầy đủ các tập tin .

Non-Working Phương pháp:

using (FileStream f = new FileStream(filepath, FileMode.Append,FileAccess.Write)) 
    (new StreamWriter(f)).WriteLine("somestring"); 

Với phương pháp này không có gì kết thúc lên được nối thêm vào tập tin.

Phương pháp làm việc:

using (FileStream f = new FileStream(filepath, FileMode.Append,FileAccess.Write)) 
    using (StreamWriter s = new StreamWriter(f)) 
     s.WriteLine("somestring"); 

tôi đã thực hiện một chút Googling, mà không khá biết những gì để tìm kiếm, và đã không tìm thấy bất cứ điều gì nhiều thông tin. Vì vậy, tại sao nó là vô danh StreamWriter thất bại, nơi (không vô danh? Tên?) StreamWriter hoạt động?

+2

Tôi đoán 'StreamWriter' không thực sự _write_ bất cứ điều gì cho đến khi được flushed và phương thức' Dispose' được ngầm gọi bằng cách sử dụng nó với khối 'using' sẽ tự động xóa nó. EDIT: Lưu ý rằng 'StreamWriter' có thuộc tính [AutoFlush] (http://msdn.microsoft.com/en-us/library/system.io.streamwriter.autoflush.aspx) có thể kiểm soát hành vi này khi nó tự động tuôn ra luồng bất cứ khi nào bạn viết mà tôi đoán là 'false' theo mặc định. –

+2

Điều này đã được trả lời rồi, nhưng tại sao bạn lại muốn định dạng mã như thế? Thật kinh khủng khi đọc và hiểu IMO, cũng như tăng rủi ro khi đưa ra các lỗi thông qua các lỗi định dạng đơn giản. Tôi là một fan hâm mộ lớn của niềng răng - luôn luôn! – TheCodeKing

+0

@ TheCodeKing nếu nó đã được trả lời rồi bạn có phiền khi cung cấp liên kết không? Tôi thành thật tìm kiếm nó và xem xét mọi câu trả lời được đề xuất trước khi đăng và không thấy bất cứ điều gì trả lời khá nhiều (chủ yếu là do tôi sử dụng một chức năng ẩn danh.) Ngoài ra, tôi không ở đây để tranh luận về những thứ có nhiều nhất một phần phong cách và dựa trên sở thích. Mã IMO rải rác với niềng răng không thực sự cần thiết là khó đọc hơn. –

Trả lời

19

Có vẻ như bạn không tuôn dòng.

http://msdn.microsoft.com/en-us/library/system.io.stream.flush.aspx

Dường như StreamWriter ghi vào một bộ đệm trước khi viết đến đích cuối cùng, trong trường hợp này, các tập tin. Bạn cũng có thể đặt thuộc tính AutoFlush và không phải xóa nó một cách rõ ràng.

http://msdn.microsoft.com/en-us/library/system.io.streamwriter.autoflush.aspx

Để trả lời câu hỏi của bạn, khi bạn sử dụng "sử dụng" khối, nó gọi vứt bỏ trên StreamWriter, mà phải ở Flush gọi lần lượt.

+0

Hơi khó thiết lập thuộc tính AutoFlush trên một 'StreamWriter' ẩn danh, bạn có nghĩ vậy không? Trừ khi tôi đang thiếu một cái gì đó. –

+2

Bạn không bao giờ nên tạo ra các cá thể vô danh của các kiểu thực thi IDisposable. – xxbbcc

+2

Tôi sẽ không khuyên bạn nên sử dụng AutoFlush và không xử lý đối tượng. Nếu một đồ vật dùng một lần, nó phải được xử lý. – dtb

7

Sự khác biệt giữa hai đoạn mã là việc sử dụng using. The using statement đặt đối tượng ở cuối khối.

A StreamWriter dữ liệu bộ đệm trước khi ghi nó vào luồng cơ bản. Vứt bỏ bộ đệm StreamWriter. Nếu bạn không xóa bộ đệm, không có gì được viết.

Từ MSDN:

Bạn phải gọi Close để đảm bảo rằng tất cả các dữ liệu được ghi một cách chính xác ra dòng cơ bản.

Xem thêm: When should I use “using” blocks in C#?

+0

Không phải là một nỗi đau, bởi vì tôi đã nhiều hơn hoặc ít hơn giả định này đã, nhưng nó sẽ có thể cho bạn để thêm một số tài liệu tham khảo đến nơi tôi có thể tìm thấy thông tin này trực tuyến? Điều này càng nhiều vì lợi ích của người khác vì nó là của riêng tôi. –

Các vấn đề liên quan