将StreamReader返回到开头
我正在逐行阅读文件,我希望能够通过调用方法Rewind()
重新启动读取。
我如何操作我的System.IO.StreamReader
和/或其底层System.IO.FileStream
重新开始读取文件?
我有聪明的想法使用FileStream.Seek(long, SeekOffset)
来移动文件,但它没有影响封闭的System.IO.StreamReader
。 我可以Close()
并重新分配stream和读者参考,但我希望有一个更好的方法。
您需要在stream上寻找,就像您一样,然后在StreamReader
上调用DiscardBufferedData
。 文档在这里 :
编辑:添加代码示例:
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
我用这个方法:
System.IO.StreamReader reader = new System.IO.StreamReader("file.txt") //end of reading reader.DiscardBufferedData(); reader.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);
如果BaseStream
实际上可以将Position
属性设置为0,这一切都很好。
如果你不能(例如将HttpWebResponse
stream),那么一个好的select是将stream复制到一个MemoryStream
…那里你可以设置Position
为0,并尽可能多地重新启动Stream
。
艾米的答案将工作在一些文件,但取决于基础stream的编码,你可能会得到意想不到的结果。
例如,如果数据stream是UTF-8并具有前导码,则StreamReader将使用它来检测编码,然后closures一些内部标志,告诉它检测编码并检查前导码。 如果您将stream的位置重置为开始,则stream读取器现在将再次使用前导码,但是它将再次将其包含在输出中。 没有公开的方法来重置此编码和前导码状态,所以如果您需要“倒带”stream读取器,最安全的事情就是如图所示将底层streamsearch到开头(或设置位置),并创build一个新的StreamReader,只是在StreamReader上调用DiscardBufferedData()是不够的。
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; } }
问题是寻找某种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()); }