高级TextReader到EndOfFile

时间:2011-07-26 02:15:28

标签: c# .net

我有一个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但找不到任何有用的东西。

由于我是社区的新手,我想我会看到有人知道他们头脑中的答案。

2 个答案:

答案 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   方法