C# 将 StreamReader 返回到开头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2053206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Return StreamReader to Beginning
提问by Chris
I'm reading a file in line-by-line and I want to be able to restart the read by calling a method Rewind()
.
我正在逐行读取文件,并且希望能够通过调用方法重新开始读取Rewind()
。
How can I manipulate my System.IO.StreamReader
and/or its underlying System.IO.FileStream
to start over with reading the file?
如何操作我的System.IO.StreamReader
和/或其底层代码System.IO.FileStream
以重新开始读取文件?
I got the clever idea to use FileStream.Seek(long, SeekOffset)
to move around the file, but it has no effect the enclosing System.IO.StreamReader
. I could Close()
and reassign both the stream and the reader referecnes, but I'm hoping there's a better way.
我有一个聪明的想法来FileStream.Seek(long, SeekOffset)
移动文件,但它对封闭的System.IO.StreamReader
. 我可以Close()
重新分配流和读者引用,但我希望有更好的方法。
采纳答案by Amy
You need to seek on the stream, like you did, then call DiscardBufferedData
on the StreamReader
. Documentation here:
你需要寻求流,像你这样,然后调用DiscardBufferedData
上StreamReader
。文档在这里:
Edit: Adding code example:
编辑:添加代码示例:
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
回答by TheBoyan
This is all good if the BaseStream
can actually be set Position
property to 0.
如果BaseStream
实际上可以将Position
属性设置为 0,这一切都很好。
If you cannot (example would be a HttpWebResponse
stream) then a good option would be to copy the stream to a MemoryStream
...there you can set Position
to 0 and restart the Stream
as much as you want.
如果你不能(例如一个HttpWebResponse
流),那么一个不错的选择是将流复制到MemoryStream
......那里你可以设置Position
为 0 并Stream
根据需要重新启动。
回答by Eamon
Amy's answer will work on some files but depending on the underlying stream's encoding, you may get unexpected results.
Amy 的回答适用于某些文件,但根据底层流的编码,您可能会得到意想不到的结果。
For example if the stream is UTF-8 and has a preamble, then the StreamReader will use this to detect the encoding and then switch off some internal flags that tells it to detect the encoding and check the preamble. If you reset the stream's position to the beginning, the stream reader will now consume the preamble again but it will include it in the output the second time. There is no public methods to reset this encoding and preamble state so the safest thing to do if you need to "rewind" a stream reader is to seek the underlying stream to the beginning (or set position) as shown and create a new StreamReader, just calling DiscardBufferedData() on the StreamReader will not be sufficient.
例如,如果流是 UTF-8 并且有前导码,那么 StreamReader 将使用它来检测编码,然后关闭一些内部标志,告诉它检测编码并检查前导码。如果您将流的位置重置为开头,流读取器现在将再次使用前导码,但它会第二次将其包含在输出中。没有公共方法可以重置此编码和前导码状态,因此如果您需要“倒带”流读取器,最安全的做法是将底层流寻找到如图所示的开头(或设置位置)并创建一个新的 StreamReader,仅在 StreamReader 上调用 DiscardBufferedData() 是不够的。
回答by Hance Doofenshmirts
I use this method:
我用这个方法:
System.IO.StreamReader reader = new System.IO.StreamReader("file.txt")
//end of reading
reader.DiscardBufferedData();
reader.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);
回答by Md Shahriar
The question is looking for some kind of StreamReader.Rewind()
method.
You are looking for StreamReader.BaseStream.Position = 0;
which sets the reader back to the beginning so it can be read again.
问题是寻找某种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());
}
回答by vyv
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;
}
}