2011-09-12 20 views
4

使用StreamReader,如果你處理底層流,我認爲你不應該再讀。在底層流佈局之後使用StreamReader?

,這是真的表明this問題,在它的建議,你不必處置StreamWriter的(在他們的情況),如果底層流的生活在別處處理。

但事實並非如此。我所做的是以下幾點:

我有一個文件名爲delme.txt包含以下

abc 
def 
ghi 

在我運行此:

Stream s = File.OpenRead(@"C:\delme.txt"); 
    StreamReader sr = new StreamReader(s, Encoding.ASCII); 

    Console.WriteLine(sr.ReadLine()); 

    s.Dispose(); 

    Console.WriteLine(sr.ReadLine()); 

,其結果是:

abc 
def 

這怎麼可能?

回答

10

您的StreamReader已將下一行讀入其緩衝區。
它將不會回到源Stream,直到其緩衝區中的數據用完。

事實上,在這種情況下它不可能拋出異常,因爲沒有冪等的方法來確定是否已經處置了Stream。 (有沒有IsDisposed屬性)

+0

啊,謝謝 - 這解釋了它。我忘記了緩衝區。 –

5

爲了增加@SLaks答案,這裏將展示(使用文件與一對夫婦千行文字):

 Stream s = File.OpenRead(path); 
     StreamReader sr = new StreamReader(s, Encoding.ASCII); 

     Console.WriteLine(sr.ReadLine()); 

     s.Dispose(); 

     int i = 1; 
     try 
     { 
      while (!sr.EndOfStream) 
      { 
       Console.WriteLine(sr.ReadLine()); 
       i++; 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 

     Console.WriteLine(i + " lines total"); 

     Console.ReadLine(); 

它會打印出很多很多線,就像幾百,然後會拋出一個例外。我的輸出端是這樣的:

qrs 
tuv 
wxy 
zab 
cde 
fgh 
ijk 
lmn 
Cannot access a closed file. 
204 lines total 

其實我們看到有對StreamReader這需要一個參數bufferSize作爲第四個參數的構造函數:

StreamReader sr = new StreamReader(s, Encoding.ASCII, false, 10000); 

使用10000,它實際上打印出總在碰撞之前我爲1248條線。此外,您可以使用的最小可能值爲1,在這種情況下,它仍可預取25行。

+0

謝謝。代碼+1 –

0

你需要在這裏理解什麼是配置試圖做什麼。

http://msdn.microsoft.com/en-us/library/ms227563.aspx

它說的TextReader將是如果TextReader的完成不可用狀態。也許,因爲它沒有讀取所有內容,所以不考慮完成;因此,您可以繼續使用它。這是我的猜測。