2013-05-13 50 views
4

我有了3線如下.txt文件:瞭解streamreader和internalbuffer?

A50

B25

C25

這是我的代碼:

FileStream fs = new FileStream(@"E:\1.txt", FileMode.Open); 
StreamReader sr = new StreamReader(fs); 
textBox1.AppendText(sr.ReadLine() + "\r\n"); 
textBox1.AppendText(fs.Position.ToString()); 

現在運行後以上代碼,輸出將是:

A50

我的問題是,爲什麼位置值是14?爲什麼它不是4,因爲流的指針會指向第一行A50末尾的'\ n'字符?這與內部緩衝區有關嗎?什麼是內部緩衝區以及它如何與流讀取器一起工作?

對不起英語不好。

+0

請注意,即使「StreamReader」沒有讀取任何額外的數據,文件位置仍然至少爲8,因爲每個字符佔用兩個字節,而不是一個。你確定你想要字節而不是字符嗎? (字符需要2個字節 - 這是默認的,除非你使用ASCII或ANSI文本。) – 2013-05-13 18:37:31

+0

@MthetheWWatson:字符*可能會佔用多於一個字節。你提到了ASCII和ANSI。雖然沒有ANSI編碼,但有很多* 8位編碼。 UTF-8中的單個字符長度可以是1到7個字節。說「每個字符佔用兩個字節」僅適用於相對少量的編碼。 – 2013-05-13 19:02:31

+0

@JimMischel儘管如此,如果你看看OP發佈的實際代碼,你可以看到他使用的是默認編碼,所以每個字符肯定至少有2個字節。我所做的一點是,對於* default *編碼,每個字符(至少)爲2個字節,這很重要。 – 2013-05-13 19:17:47

回答

3

我的問題是爲什麼位置值是14?

StreamReader爲了在基礎流上執行相對較少的讀操作而具有「overread」。是的,它與內部緩衝區有關 - 它的想法是它會對基礎流執行「粗糙」讀取操作,通常讀取的內容比嚴格需要的要多,以滿足當前操作 - 從而防止大量單字節讀取。

要一次讀取一行,沒有過度讀取的風險,它必須一次讀取一個字節 - 這可能不是單個字符。根據流的實現情況,這可能效率不高。相反,它會讀入一個隱藏的實現細節(您沒有直接訪問緩衝區)的緩衝區,然後滿足來自該緩衝區的請求,直到它必須再次從流中讀取。

+0

有什麼辦法可以以單字節的方式讀取文件嗎? – AWT 2013-05-13 18:33:43

+2

@AbdulwadoudTah你不需要StreamReader;你可以使用['FileStream.ReadByte()'](http://msdn.microsoft.com/en-us/library/system.io.filestream.readbyte.aspx)你確定你不需要讀取字符而不是字節呢? – 2013-05-13 18:38:25

+1

@AbdulwadoudTah:你爲什麼想要?這裏的大圖是什麼? – 2013-05-13 18:39:50

3

StreamReader將數據從磁盤讀取到內部緩衝區,然後滿足來自該緩衝區的請求。

它以這種方式工作,以減少調用操作系統數據的次數。如果沒有內部緩衝區,那就必須這樣做:

while (not end-of-file and character != newline) 
{ 
    read next character and append to string 
} 

與內部緩衝器,它讀取數據的一大塊(默認是像4K字節,但可以改變)到內存中。然後它可以快速掃描該數據塊以獲得換行符並返回字符串。

+0

這很有幫助,謝謝。 – AWT 2013-05-13 18:36:46