我有一个textReader,在特定的实例中,我希望能够快速前进到文件的末尾,以便其他可能包含对该对象的引用的类将无法调用tr.ReadLine()而无法获取空。
这是一个大文件。我不能使用TextReader.ReadToEnd(),因为它经常会导致OutOfMemoryException
我想我会问社区是否有办法在不使用TextReader.ReadToEnd()的情况下查找流,该文件返回文件中所有数据的字符串。
目前的方法,效率低下。
以下示例代码是模拟。显然我没有直接打开一个带有if语句的文件,询问我是否想要读到最后。
TextReader tr = new StreamReader("Largefile");
if(needToAdvanceToEndOfFile)
{
while(tr.ReadLine() != null) { }
}
所需解决方案(请注意,此代码块包含由于存在外部错误风险而无法使用的假“概念”方法或方法)
TextReader tr = new StreamReader("Largefile");
if(needToAdvanceToEndOfFile)
{
tr.SeekToEnd(); // A method that does not return anything. This method does not exist.
// tr.ReadToEnd() not acceptable as it can lead to OutOfMemoryException error as it is very large file.
}
一种可能的替代方法是使用tr.ReadBlock(args)以更大的块读取文件。
我戳了一下((StreamReader)tr).BaseStream但找不到任何有用的东西。
由于我是社区的新手,我想我会看到有人知道他们头脑中的答案。
答案 0 :(得分:2)
使用
reader.BaseStream.Seek(0, SeekOrigin.End);
测试:
using (StreamReader reader = new StreamReader(@"Your Large File"))
{
reader.BaseStream.Seek(0, SeekOrigin.End);
int read = reader.Read();//read will be -1 since you are at the end of the stream
}
修改:使用您的代码进行测试:
using (TextReader tr = new StreamReader("C:\\test.txt"))//test.txt is a file that has data and lines
{
((StreamReader)tr).BaseStream.Seek(0, SeekOrigin.End);
string foo = tr.ReadLine();
Debug.WriteLine(foo ?? "foo is null");//foo is null
int read = tr.Read();
Debug.WriteLine(read);//-1
}
答案 1 :(得分:2)
如果您已经读取了任何文件内容,则必须丢弃任何缓冲数据 - 因为数据是缓冲的,即使您在底层流中寻找底层流,也可能获得内容 - 工作示例:
StreamReader sr = new StreamReader(fileName);
string sampleLine = sr.ReadLine();
//discard all buffered data and seek to end
sr.DiscardBufferedData();
sr.BaseStream.Seek(0, SeekOrigin.End);
documentation中提到的问题是
StreamReader类缓冲来自基础流的输入 你调用其中一种Read方法。如果你操纵位置 将数据读入缓冲区后的基础流的位置 基础流的可能与内部的位置不匹配 缓冲。 要重置内部缓冲区,请调用DiscardBufferedData 方法强>