使用StreamReader读取最多一个字符串

时间:2014-10-19 19:51:12

标签: .net streamreader

我在使用StreamReader读取文件的.NET应用程序中编写文件解析器。要解析的文件以以"<eoh>"结尾的标头开头。我想要从头开始读取或忽略所有内容。实际数据在此之后开始。

该文件不是基于行的。所有东西都只有这样的标记字符串才能显示。所以我不能使用ReadLine。

如果不一次读取一个字符并实现状态机来识别标记工作字符,我该怎么做?我特意寻找StreamReader.SkipUntilAfter(string)StreamReader.ReadUntil(string)等方法。

哦,这个项目仍在使用.NET 2.0,所以这里不需要LINQ。如果有人建议使用它,我可能会解决这个问题。

1 个答案:

答案 0 :(得分:1)

TextReader一般已经逐字逐句阅读。他们使用缓冲区以便更快,但StreamReader的缓冲区与仅提前读取并仅拉到<eoh>之间没有任何区别。出于同样的原因,在该标题之后也没有更好的方法可以跳过。绝对最佳情况是内置函数,它只是直观地抽象底层代码,因此不是特别有用。

如果你因为某种原因不相信我,here's the source code

此外,值得注意的是,无论什么,您都必须逐个字符地查看。即使你有办法将它们拉入内存而不这样做,比较两个string是一个逐字符操作。所以你不会保存任何东西。

就个人而言,我只是喜欢这样的事情。它需要TextReader和标题结束字符串,并通过reader读取,直到找到eoh。然后,它返回bool是否找到了标记。

public bool SkipUntilAfterHeader(TextReader reader, string eoh)
{
    int eohGuessIndex = 0;
    int next;

    while ((next = reader.Read()) != -1)
    {
        char c = (char)next;

        if (c == eoh[eohGuessIndex])
        {
            eohGuessIndex++;
            if (eohGuessIndex == eoh.Length)
            {
                return true;
            }
        }
        else
        {
            eohGuessIndex = 0;
        }
    }

    return false;
}

我不确定.NET 2.0有没有,所以我从头开始写了一些可能有或没有的东西。但性能不应受此影响。这方面的一个不错的方面是,您还可以轻松添加StringBuilder out参数,该参数将传递标题信息,以防您以后想要这样做。

然后,使用非常简单。

public void ReadFile(string path)
{
    using (StreamReader reader = new StreamReader(path))
    {
        if (SkipUntilAfterHeader(reader, "<eoh>"))
        {
            // read file
        }
        else
        {
            // corrupt file
        }
    }
}

但实际上,读取整个文件并返回相关部分可能更容易。与可读性相比,它只取决于性能的重要程度。

在经典不好的形式中,请注意我没有测试 - 甚至编译 - 任何此类。但它应该相对容易修复,即使它不起作用。