Reading the next line of a file only once

10,706

Solution 1

Simply use

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

and process the file with a for (int i = 0; i < lines.Length; i ++) loop.

For a big file, simply cache the 'previous line' or do an out-of-band ReadLine().

Solution 2

Here is an idiom to process the current line you while having the next line already available:

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();
        }
    }
}

This is basically a queue with a maximum of two items in it, or "one line read-ahead".

Edit: Simplified.

Solution 3

Can you not just call reader.ReadLine() again? Or is the problem that you then need to use the line in the next iteration of the loop?

If it's a reasonably small file, have you considered reading the whole file using File.ReadAllLines()? That would probably make it simpler, although obviously a little less clean in other ways, and more memory-hungry for large files.

EDIT: Here's some code as an alternative:

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
        }
    }
}
Share:
10,706
techmanc
Author by

techmanc

Updated on June 22, 2022

Comments

  • techmanc
    techmanc almost 2 years

    I have an application that reads information from a text file and then categorizes them and puts them onto a Database. For one category, I need to check the line that comes right after the current line and look for a certain keyword?

    How do i get to read this line? This should happen when the streamreader has the current line already open....

    I'm using c# on VS2010.

    Edit:

    All of the code below is in a while (!sReader.EndOfStream) loop

     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.....
    

    Also, the .log files that are opened might go upto 50 Mb types... ! Which is why i dont really prefer reading all lines and keeping track!