将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,这一切都很好。

如果你不能(例如将HttpWebResponsestream),那么一个好的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()); }