C# 将StreamReader返回到开始
我正在逐行读取文件,我希望能够通过调用方法C# 将StreamReader返回到开始,c#,.net,C#,.net,我正在逐行读取文件,我希望能够通过调用方法revind()重新开始读取 如何操作我的System.IO.StreamReader和/或其底层System.IO.FileStream重新开始读取文件 我想出了一个聪明的主意,使用FileStream.Seek(long,SeekOffset)在文件中移动,但它对封装的System.IO.StreamReader没有任何影响。我可以Close()并重新分配流和读卡器引用,但我希望有更好的方法。您需要像以前一样在流上查找,然后在流读卡器上调用丢弃缓冲数
revind()
重新开始读取
如何操作我的System.IO.StreamReader
和/或其底层System.IO.FileStream
重新开始读取文件
我想出了一个聪明的主意,使用
FileStream.Seek(long,SeekOffset)
在文件中移动,但它对封装的System.IO.StreamReader
没有任何影响。我可以Close()
并重新分配流和读卡器引用,但我希望有更好的方法。您需要像以前一样在流上查找,然后在流读卡器上调用丢弃缓冲数据。文件:
编辑:添加代码示例:
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
…在那里,您可以将位置设置为0,然后根据需要重新启动流,你可能会得到意想不到的结果
例如,如果流为UTF-8且具有前导码,则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());
}
public long ReadList(字符串文件名,动作动作,长位置=0)
{
如果(!File.Exists(fileName))返回0;
使用(var reader=newstreamreader(File.Open(fileName,FileMode.Open,FileAccess.Read,FileShare.ReadWrite),System.Text.Encoding.Unicode))
{
如果(位置>0)reader.BaseStream.position=位置;
而(!reader.EndOfStream)
{
操作(reader.ReadLine());
}
返回reader.BaseStream.Position;
}
}
我创建了一个简单的方法,可以用来重置StreamReader
using (var reader = StreamReader(filePath))
{
reader.ReadLine();
reader.ReadLine();
}
ResetReader();
private static void ResetStream(StreamReader reader)
{
reader.DiscardBufferedData();
reader.BaseStream.Seek(0, SeekOrigin.Begin);
}
在任何不是简单ANSI文本文件的文件(或者任何具有编码前置的文件)上执行此操作时,请务必小心。有关更多详细信息,请参见下面的回答。您忘记了using子句/IDisposable模式。NET 4.0的新功能是StreamReader(stream,Encoding.UTF8,true,1024,true)和新的StreamWriter(stream,Encoding.UTF8,1024,true)克服了中断的IDisposable模式(关闭StreamReader/Writer关闭底层流…即使M$也不总是正确的,至少一开始是这样)。如果需要多次读取流,请使用两个或多个StreamReader,每个StreamReader都位于各自的using子句中(不嵌套在彼此内部)。StreamWriter也是如此。根据文档,调用DiscardBufferedData应该是非常罕见的。这对我来说不太合适。读取第一行后,将显示两次正在读取的HTML文件,然后使用建议的重置。也许它适用于某些情况,但不适用于我的情况;sr.BufferedData();请提供一些信息,说明为什么此代码片段解决了问题中描述的问题。如何将流复制到内存流?哦,我需要将响应设置回位置0并重新启动,但如何重新启动?此方法允许您处理文本文件以创建新的文本文件,并允许您避免复制重复的文本行。下面是在BaseStream.Position=0之后使用DiscardBufferedData()的示例;
public static void removeDuplicatedLinesBigFile2(string inFile, string outFile)
{
int counter1 = 0, counter2 = 0;
string line1, line2;
bool band = false;
// Read the file and display it line by line.
System.IO.StreamReader fileIN1 = new System.IO.StreamReader(inFile);
System.IO.StreamReader fileIN2 = new System.IO.StreamReader(inFile);
System.IO.StreamWriter fileOut = new System.IO.StreamWriter(outFile);
while ((line1 = fileIN1.ReadLine()) != null)
{
//band = false;
int counter = 0;
fileIN2.BaseStream.Position = 0;
fileIN2.DiscardBufferedData();
while ((line2 = fileIN2.ReadLine()) != null)
{
if (line1.Equals(line2))
counter++;
if (counter > 1)
break;
}
fileOut.WriteLine(line1);
counter1++;
}
fileIN1.Close();
fileIN2.Close();
Console.WriteLine("Total Text Rows Copied: {0}", counter1);
}
using (var reader = StreamReader(filePath))
{
reader.ReadLine();
reader.ReadLine();
}
ResetReader();
private static void ResetStream(StreamReader reader)
{
reader.DiscardBufferedData();
reader.BaseStream.Seek(0, SeekOrigin.Begin);
}