Home > Back-end >  Reading sections of a txt file in C#
Reading sections of a txt file in C#

Time:03-01

I have a bunch of Powershell scripts which are executed and the full transcript is saved in a .log file in a specific location. I can read the .log file using:

string[] text = System.IO.File.ReadAllLines(@"D:\install.log");
foreach (string line in text)
{
    Console.WriteLine(line);
}

In this .log file, there is a lot of text and what I am trying to do is read specific sections of the .log file and do operations based on those. So for example the .log file contains something like this:

Executing script no. 1
#####LOTS OF POWERSHELL OUTPUT LINES HERE#####
Executing script no. 2
#####LOTS OF POWERSHELL OUTPUT LINES HERE#####

What I want to be able to do is read the text from Executing script no. 1 and up until Executing script no. 2 and then do some operations accordingly. And then move on to script no. 2 and then so on.

Also, something to note here is that the .log file is being updated as the Powershell scripts are being executed. So when I start reading the .log file, it continues being updated until all the scripts have been executed and I see: Transcript ended at the end of the .log file.

How can I read the .log file in sections here?

CodePudding user response:

You can approach your problem with this pattern

List<string> section = new List<string>();
foreach (string line in System.IO.File.ReadLines(@"D:\install.log"))
{
    if (line.StartsWith("Executing script no"))
    {
        ProcessSection(section);
        section = new List<string>();
    }
    section.Add(line);

}

// Process the last section....
ProcessSection(section);    

First, do not load all lines together in memory but read one by one accumulating them in a List of strings that represents the content of a section. Then when you find the line that start the section pass everything to your processing code and restart with a new section data

void ProcessSection(List<string> sectionData)
{
    if(sectionData.Count == 0)
       return;

    // now you can loop over the strings in sectionData or
    // rejoin everything with
    // string.Join(Environment.NewLine,sectionData);
}

But, from your comment below, it seems that another process is writing to the file while you try to read it. In this context, File.ReadLines could fail because it will try to lock the file making impossible to the other process the write operation. (Or failing itself because it cannot lock the file).

In this context your need to read line by line in a different way

using (var fs = new FileStream("D:\\install.log", FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 0x1000, FileOptions.SequentialScan))
using (var sr = new StreamReader(fs, Encoding.UTF8))
{
    string line;
    while ((line = sr.ReadLine()) != null)
    {
        // as above
    }
}

CodePudding user response:

you can use the IndexOf() fucntion to get the starting point of your scripts and extract the part from inbetween

string[] text = System.IO.File.ReadAllLines(@"D:\install.log");
int start = text.IndexOf("Executing script no. 1")
int end   = text.IndexOf("Executing script no. 2")
string scriptOneOutput = text.Substring(start , end-start);
//now scriptOneOutput  should only contain the output from script one and you can process it
  •  Tags:  
  • c#
  • Related