我正在逐行讀取文件,我希望能夠通過調用方法Rewind()
重新啓動讀取。返回StreamReader開始
如何操作我的System.IO.StreamReader
和/或其底層System.IO.FileStream
重新開始閱讀文件?
我得到巧妙的想法,使用FileStream.Seek(long, SeekOffset)
圍繞文件移動,但它沒有影響圍繞System.IO.StreamReader
。我可以Close()
並重新分配流和讀者參考,但我希望有更好的方法。
我正在逐行讀取文件,我希望能夠通過調用方法Rewind()
重新啓動讀取。返回StreamReader開始
如何操作我的System.IO.StreamReader
和/或其底層System.IO.FileStream
重新開始閱讀文件?
我得到巧妙的想法,使用FileStream.Seek(long, SeekOffset)
圍繞文件移動,但它沒有影響圍繞System.IO.StreamReader
。我可以Close()
並重新分配流和讀者參考,但我希望有更好的方法。
你需要在流上尋找,就像你做的那樣,然後在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
這都是一件好事,如果BaseStream
實際上可以Position
屬性設置爲0
如果你不能(例如將是一個HttpWebResponse
流)那麼一個好的選擇是將流複製到一個MemoryStream
...那裏你可以設置Position
爲0並儘可能多地重新啓動Stream
。
艾米的答案將在一些文件上工作,但取決於基礎流的編碼,您可能會得到意想不到的結果。
例如,如果數據流是UTF-8並具有前導碼,則StreamReader將使用它來檢測編碼,然後關閉一些內部標誌,告訴它檢測編碼並檢查前導碼。如果您將流的位置重置爲開頭,那麼流讀取器現在將再次使用前導碼,但它將第二次將其包含在輸出中。沒有公共方法來重置此編碼和前導碼狀態,因此如果您需要「倒帶」流讀取器,最安全的方法就是如圖所示將底層流搜索到開頭(或設置位置),並創建一個新的StreamReader,只是在StreamReader上調用DiscardBufferedData()是不夠的。
我用這個方法:
System.IO.StreamReader reader = new System.IO.StreamReader("file.txt")
//end of reading
reader.DiscardBufferedData();
reader.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);
的問題是尋找某種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());
}
這並不適合我。正在讀入的HTML文件在讀取第一行後顯示兩次,然後使用建議的重置。也許它適用於某些情況,但不適用於我的情況。 – JohnH 2016-11-10 16:06:52
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;
}
}
請提供一些信息,說明爲什麼這段代碼片段解決了問題中描述的問題。 – 2016-11-22 18:37:53
在不是簡單的ANSI文本文件(或者說有一個編碼碼前導任何文件)的任何文件執行此操作時要小心。有關更多詳情,請參閱下面的答案。 – Eamon 2015-07-16 02:05:58
您忘記了使用條款/ 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