只读取文件的下一行一次

3
我有一个应用程序,它从文本文件中读取信息,然后对其进行分类并将其放入数据库中。对于一个类别,我需要检查当前行后面的行,并查找特定的关键词?
当streamreader已经打开当前行时,如何读取此行?
我正在使用VS2010上的C#。
编辑:
下面的所有代码都在while(!sReader.EndOfStream)循环中。
 string line = sReader.ReadLine(); //Note: this is used way above and lots of things are done before we come to this loop

 for (int i = 0; i < filter_length; i++)
 {
       if (searchpattern_queries[i].IsMatch(line) == true)
       {
               logmessagtype = selected_queries[i];

               //*Here i need to add a if condition to check if the type is "RESTARTS" and i need to get the next line to do more classification. I need to get that line only to classify the current one. So, I'd want it to be open independently *

               hit = 1;
               if (logmessagtype == "AL-UNDEF")
               {
                   string alid = AlarmID_Search(line);
                   string query = "SELECT Severity from Alarms WHERE ALID like '" +alid +"'";
                   OleDbCommand cmdo = new OleDbCommand(query, conn);
                   OleDbDataReader reader;
                   reader = cmdo.ExecuteReader();
                   while (reader.Read())
                   {
                        if (reader.GetString(0).ToString() == null)
                        { }
                        else
                        {
                             string severity = reader.GetString(0).ToString();
                             if (severity == "1")
                                 //Keeps going on.....

此外,打开的.log文件可能会达到50MB之类的大小...!这就是为什么我不太喜欢阅读所有行并跟踪的原因!

StreamReader没有“打开一行”的概念。 - H H
你不能直接调用 StreamReader.ReadLine() 吗? - rossipedia
@Bryan:那不会只是移动到那一行吗?我需要那一行再次被读取以进行下一次迭代。 - techmanc
techmanc,如果您提供一个大纲,这个问题似乎很容易解决。现在需要大量的猜测和假设。请展示一下您目前尝试过的内容。 - H H
最简单的方法是使用:读取所有行并检查i+1… 对我有用.. :) 谢谢大家。 - techmanc
5个回答

5

这里有一个习语,可以在处理当前行时已经准备好下一行:

public void ProcessFile(string filename)
{
    string line = null;
    string nextLine = null;
    using (StreamReader reader = new StreamReader(filename))
    {
        line = reader.ReadLine();
        nextLine = reader.ReadLine();
        while (line != null)
        {
            // Process line (possibly using nextLine).

            line = nextLine;
            nextLine = reader.ReadLine();
        }
    }
}

这基本上是一个具有最多两个项目或“一行预读”的队列编辑:简化。

4

只需简单地使用

 string[] lines = File.ReadAllLines(filename);

使用 for (int i = 0; i < lines.Length; i ++) 循环处理文件。

对于大文件,可以简单地缓存“前一行”或进行带外 ReadLine() 操作。


1

你不能再次调用reader.ReadLine()吗?还是说你在下一次循环中需要使用这行代码?

如果文件比较小,你考虑过使用File.ReadAllLines()来读取整个文件吗?这样可能会更简单,尽管在其他方面可能不那么干净,并且对于大文件而言,需要更多的内存。

编辑:以下是另一个选择的代码:

using (TextReader reader = File.OpenText(filename))
{
    string line = null; // Need to read to start with

    while (true)
    {
        if (line == null)
        {
            line = reader.ReadLine();
            // Check for end of file...
            if (line == null)
            {
                break;
            }
        }
        if (line.Contains("Magic category"))
        {
            string lastLine = line;
            line = reader.ReadLine(); // Won't read again next iteration
        }
        else
        {
            // Process line as normal...
            line = null; // Need to read again next time
        }
    }
}

我需要下一次迭代的那一行,只是需要它作为参考来分类当前行。有没有办法可以从当前readline中单独打开这一行……我考虑过读取所有行……但是文件非常庞大的情况下不太理想! - techmanc
@techmanc:“巨大”到底有多大?你可以随时保留你读取的那一行的副本,关键是要确保你使用它而不是读取下一行。 - Jon Skeet
我读了100个文件,并将它们放入一个迭代的数据库中。而且一些文件可能达到50-100 MB! - techmanc
@techmanc:嗯,其实那并不是太多——如果这样可以让代码更简单,我会倾向于完全读取每个文件以处理它。不过,我会提供一些替代代码…… - Jon Skeet

0

我不是一个文件IO专家...但为什么不这样做:

在你开始读取行之前,声明两个变量。

string currentLine = string.Empty
string previousLine = string.Empty

当你阅读时,然后...
previousLine = currentLine;
currentLine = reader.ReadLine();

0
你可以保存流的位置,然后在调用ReadLine之后将其回溯到该位置。然而,这种方法效率相对较低。
我会将ReadLine的结果存储到一个"缓冲区"中,并尽可能使用该缓冲区作为数据源。当缓冲区为空时,则使用ReadLine。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接