2010-01-12 100 views
53

我正在逐行讀取文件,我希望能夠通過調用方法Rewind()重新啓動讀取。返回StreamReader開始

如何操作我的System.IO.StreamReader和/或其底層System.IO.FileStream重新開始閱讀文件?

我得到巧妙的想法,使用FileStream.Seek(long, SeekOffset)圍繞文件移動,但它沒有影響圍繞System.IO.StreamReader。我可以Close()並重新分配流和讀者參考,但我希望有更好的方法。

回答

93

你需要在流上尋找,就像你做的那樣,然後在StreamReader上致電DiscardBufferedData。文檔here

編輯:添加代碼示例:

Stream s = new MemoryStream(); 
StreamReader sr = new StreamReader(s); 
// later... after we read stuff 
s.Position = 0; 
sr.DiscardBufferedData();  // reader now reading from position 0 
+4

在不是簡單的ANSI文本文件(或者說有一個編碼碼前導任何文件)的任何文件執行此操作時要小心。有關更多詳情,請參閱下面的答案。 – Eamon 2015-07-16 02:05:58

+0

您忘記了使用條款/ IDisposable模式。新的.NET 4.0是StreamReader(stream,Encoding.UTF8,true,1024,true)和新的StreamWriter(stream,Encoding.UTF8,1024,true)克服了破碎的IDisposable模式(關閉StreamReader/Writer關閉底層流...即使M $並不總是對的,至少在第一時間)。如果您需要不止一次從流中讀取數據,請使用兩個或多個StreamReader,每個StreamReader都使用自己的子句(而不是彼此嵌套)。與StreamWriter一樣。根據文檔,您應該很少會調用DiscardBufferedData。 – TamusJRoyce 2016-06-30 21:14:30

16

這都是一件好事,如果BaseStream實際上可以Position屬性設置爲0

如果你不能(例如將是一個HttpWebResponse流)那麼一個好的選擇是將流複製到一個MemoryStream ...那裏你可以設置Position爲0並儘可能多地重新啓動Stream

14

艾米的答案將在一些文件上工作,但取決於基礎流的編碼,您可能會得到意想不到的結果。

例如,如果數據流是UTF-8並具有前導碼,則StreamReader將使用它來檢測編碼,然後關閉一些內部標誌,告訴它檢測編碼並檢查前導碼。如果您將流的位置重置爲開頭,那麼流讀取器現在將再次使用前導碼,但它將第二次將其包含在輸出中。沒有公共方法來重置此編碼和前導碼狀態,因此如果您需要「倒帶」流讀取器,最安全的方法就是如圖所示將底層流搜索到開頭(或設置位置),並創建一個新的StreamReader,只是在StreamReader上調用DiscardBufferedData()是不夠的。

19

我用這個方法:

System.IO.StreamReader reader = new System.IO.StreamReader("file.txt") 
//end of reading 
reader.DiscardBufferedData(); 
reader.BaseStream.Seek(0, System.IO.SeekOrigin.Begin); 
-1

的問題是尋找某種StreamReader.Rewind()方法。 您正在尋找StreamReader.BaseStream.Position = 0;,它將閱讀器重新設置爲開始,以便可以再次閱讀。

StreamReader sr = new StreamReader("H:/kate/rani.txt"); 

Console.WriteLine(sr.ReadToEnd()); 

sr.BaseStream.Position = 0; 

Console.WriteLine("----------------------------------"); 

while (!sr.EndOfStream) 
{ 
    Console.WriteLine(sr.ReadLine()); 
} 
+0

這並不適合我。正在讀入的HTML文件在讀取第一行後顯示兩次,然後使用建議的重置。也許它適用於某些情況,但不適用於我的情況。 – JohnH 2016-11-10 16:06:52

1
public long ReadList(string fileName, Action<string> action,long position=0) 
{ 
    if (!File.Exists(fileName)) return 0; 

    using (var reader = new StreamReader(File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite),System.Text.Encoding.Unicode)) 
    { 
    if (position > 0)reader.BaseStream.Position = position; 

    while (!reader.EndOfStream) 
    { 
     action(reader.ReadLine()); 
    } 
    return reader.BaseStream.Position; 
    } 
} 
+3

請提供一些信息,說明爲什麼這段代碼片段解決了問題中描述的問題。 – 2016-11-22 18:37:53