2012-10-24 50 views
7

Tôi có một StreamWriter mà luồng cơ bản là FileStream. Mã sau có đảm bảo rằng FileStream cũng xóa bộ đệm của nó vào tệp thực sự trên hệ thống tệp hay tôi cần gọi rõ ràng Flush() trên FileStream?StreamWriter.Flush() cũng có thể gọi FileStream.Flush() không?

using (var fs = new FileStream("blabla", FileMode.Append)) { 
    using (var sw = new StreamWriter(fs)) { 
     sw.WriteLine("Hello, I want to be flushed."); 
     sw.Flush(); //I need this to also flush onto the file, not just to the FileStream 
    } 
} 

Theo MSDN, "Flushing dòng sẽ không tuôn encoder cơ bản của nó, trừ khi bạn gọi một cách rõ ràng Flush hoặc Đóng", nhưng tôi không biết nếu một FileStream có thể được coi là một "bộ mã hóa cơ bản".

Ngoài ra, nếu tôi không chỉ định FileOptions.WriteThrough, tôi có đảm bảo rằng hệ điều hành cuối cùng sẽ ghi dòng được xóa lên đĩa ngay cả khi chương trình bị treo trước khi hai luồng đã bị đóng (giả sử ví dụ không có using {} khối , chỉ có một cuộc gọi đến Flush())?

Trong trường hợp của tôi, tôi cần để luồng mở (để ghi nhật ký), vì vậy tôi không thể sử dụng using {} khối, nhưng tôi muốn đảm bảo dữ liệu luôn được ghi vào đĩa ngay cả khi chương trình bị treo. Tôi có thể đủ khả năng để mất dữ liệu nếu có tắt nguồn và hệ điều hành chưa được xả lên đĩa, nhưng nếu không tôi cần hệ điều hành để xả ngay cả khi tôi không bao giờ gọi đúng số Close() trên luồng.

+0

Tại sao bạn không dùng thử? – opewix

+0

Tôi quan tâm để biết liệu hành vi được đảm bảo và chúng ta có thể dựa vào nó, không phải liệu nó hoạt động phần lớn thời gian. –

+0

có nó sẽ tuôn ra dòng cơ bản. Xóa tất cả bộ đệm cho người viết hiện tại và làm cho bất kỳ dữ liệu đệm nào được ghi vào luồng cơ bản. – opewix

Trả lời

7

Vâng, gọi Flush trên StreamWriter sẽ gây ra dòng cơ bản là Flush ed. 4.5 phiên bản gọi là Flush(bool,bool) chức năng riêng, được kết thúc bằng:

if (flushStream) 
{ 
    this.stream.Flush(); 
} 

đâu flushStream là tham số đầu tiên, this.stream là dòng rằng StreamWriter được xây dựng trên, và các cuộc gọi trong Flush()Flush(true,true).


(phần cũ của câu trả lời - Tôi đã là rất bùng binh trả lời Moved phần phù hợp nhất của câu trả lời cho hàng đầu.)

Nó không rõ ràng nêu ra trong tài liệu bất cứ nơi nào tôi có thể tìm thấy nó, nhưng bất kỳ lớp luồng được xây dựng bằng cách truyền cho nó một luồng khác sẽ được giả định là "sở hữu" luồng đó (trừ khi nó được gọi riêng ra khác).

Tức là, khi bạn đã xây dựng StreamWriter bằng cách sử dụng fs, bạn không nên thực hiện bất kỳ hành động trực tiếp nào trên chính mình fs.


Phần bạn trích dẫn từ MSDN liên quan đến các câu sau:

Điều này cho phép các bộ mã hóa để giữ cho nhà nước (nhân vật một phần) của nó để nó có thể mã hóa các khối tiếp theo của nhân vật một cách chính xác. Kịch bản này ảnh hưởng đến UTF8 và UTF7 trong đó các ký tự nhất định chỉ có thể được mã hóa sau khi bộ mã hóa nhận được ký tự hoặc ký tự liền kề.

Tức là, bạn có thể đã chuyển dữ liệu đến Write sao cho bạn đã cho nó một số thay thế Unicode, nhưng không phải là ký tự hoàn chỉnh. Flush sẽ không ghi những người thay thế đó vào luồng. Vì vậy, miễn là bạn luôn luôn đi qua cũng được hình thành (hoàn thành) dây để Write, bạn không cần phải quan tâm đến chính mình về điều này.


+0

Cảm ơn, điều đó giúp ích rất nhiều. Điều gì về phần thứ hai của câu hỏi? Về đảm bảo rằng hệ điều hành sẽ thực sự viết Flush tại một thời điểm nào đó ngay cả khi Stream không bao giờ đóng đúng và FileOptions.WriteThrough KHÔNG được chỉ định trong constructor FileStream? –

+0

@ErwinMayer - Tôi không chắc mình có hiểu câu hỏi hay không. Nếu bạn ** hoàn toàn **, ** chắc chắn **, * phải * đảm bảo rằng dữ liệu này sẽ truy cập vào đĩa, thì bạn gần như chắc chắn sẽ cần phải chỉ định 'WriteThrough' - nhưng bạn cũng sẽ cần một máy có vỏ đĩa với pin dự phòng, vv Nếu không, tôi nghĩ rằng sẽ luôn luôn có một cửa sổ nguy cơ nhỏ. Tôi không biết bao lâu cửa sổ này có nguy cơ, và nó có khả năng hệ điều hành (và có thể cấu hình hệ điều hành, trình điều khiển, vv) phụ thuộc - vì vậy không được xác định rõ trong khuôn khổ .NET. –

+0

True, trong trường hợp của tôi miễn là các hướng dẫn để ghi dữ liệu vào đĩa được gửi đến hệ điều hành tôi ổn. Tôi không ngại nếu hệ điều hành không ghi ngay vào đĩa. Tôi chỉ muốn chắc chắn rằng hệ điều hành sẽ ghi dữ liệu đỏ bừng ngay cả khi chương trình bị hủy bỏ và các luồng không được đóng đúng cách. –

4

Xử lý luồng được đảm bảo nếu được sử dụng với sử dụng khối!

Với một chuỗi các con suối, đóng cửa suối ngoài cùng (ở phần đầu của chuỗi) i.e StreamWriter in your case đóng toàn bộ rất nhiều i.e FileStream

Flush lực lượng phương pháp đệm bên trong để được viết immediately.Flush được tự động gọi khi dòng là closed, vì vậy bạn không bao giờ cần phải làm như sau

s.Flush();s.Close();

vì vậy, thời điểm hiện tại hầu hết các s trên cùng tream được đóng nó tuôn ra và sau đó đóng nó bên dưới dòng người cũng tuôn ra có nội dung.

Ví dụ xem xét chuỗi này

FileStream->GZipStream->StreamWriter 

Vì vậy, thời điểm bạn đóng StreamWriter

StreamWriter bừng và closes.It cũng đóng vai trò quant undelying GZipStream

GzipStream bừng và closes.It cũng đóng bên dưới FileStream

FileStream flushescloses

+1

Cảm ơn, tôi biết rằng đóng StreamWriter đóng FileStream, nhưng phần đầu tiên của câu hỏi liên quan đến việc Flush() cũng đang xếp tầng hay không. Phần thứ hai của câu hỏi liên quan đến việc liệu FileStream chưa được xử lý trước khi bị lỗi (ví dụ: không sử dụng các khối), nhưng Flush() đã được gọi, cho dù hệ điều hành vẫn sẽ ghi bộ đệm nội bộ của nó vào đĩa vật lý (miễn là không có sự cố hệ điều hành hoặc tắt nguồn của khóa học). –

+0

@ErwinMayer như tôi đã nói, 'flush' được tự động gọi khi luồng được đóng hoặc bộ đệm được lấp đầy .. Thời điểm luồng trên cùng cao nhất được đóng lại và sau đó đóng các luồng nằm bên dưới suối cũng tuôn ra ở đó .. – Anirudha

+0

Có Tuy nhiên, tôi quan tâm đến trường hợp chúng tôi không đóng bất kỳ luồng nào ... –