Search code examples
c#streamreaderdatalog

Read text file line by line using timer


StreamReader sr = new StreamReader("C:/CR EZ Test/Log.txt");    //use with IF
private void timer2_Tick(object sender, EventArgs e)
{
    if ((line = sr.ReadLine()) != null)
    {   
        //FileStream fs = File.Open("C:/CR EZ Test/Log.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        //StreamReader sr = new StreamReader(fs); //use with While can't use with }else{
        //while ((line = sr.ReadLine()) != null) 
        //{
        string[] dataLog = line.Split(new[] { ',' }, StringSplitOptions.None);
        mpa = (dataLog[1]);
        ml  = (dataLog[2]);
        lph = (dataLog[3]);
        elapsedTime = float.Parse(dataLog[4]) / 1000;

        if (testStatus > 0) time = elapsedTime.ToString("0.0");
        tb2.Value = int.Parse(dataLog[6]);

        if (chart1.Series[0].Points.Count > tb1.Value && tb1.Value > 0)
        {
            chart1.Series[0].Points.RemoveAt(0);
            chart1.Series[1].Points.RemoveAt(0);
        }
        chart1.Series[0].Points.AddXY(dataLog[5], int.Parse(dataLog[1]));
        chart1.Series[1].Points.AddXY(dataLog[5], int.Parse(dataLog[6]));
        //}
    }
    else
    {
        sr.DiscardBufferedData();
        sr.BaseStream.Seek(0, SeekOrigin.Begin);
        sr.BaseStream.Position = 0;
        //sr.Close();
        //alertTB.Text = "";
        timer2.Enabled = false;
    }
    alertTB.ForeColor = Color.Red;
    alertTB.Text = "Data Log Viewing In Progress";
}

The issue is I am reading a text file full of variables back through a GUI, like replaying a video. As the code is shown, it works and I can control the timer tick to change the replay speed. The issue is the file is in use, so I can't write to or delete the text while the file is in use, without closing it first. I would like to either be able to find a workaround of the Streamreader, or use the Filestream to Streamreader code that will allow me to edit the file while it is in use. The issue there is, I can't figure out how to make it work with the timer, it just reads the entire file very quickly. Any help or ideas are greatly appreciated.

The issue here is how to have the commented out code to:

  1. read a line of the text file,
  2. have the timer to tick
  3. then read the next line of the text file, and so on. Obviously handling the data as it arrives.

Solution

  • A Proven Working Solution

     string line;
            if (!File.Exists(logFile))
            {
                viewLog.Text = "Play";
                alertTB.ForeColor = Color.Red;
                alertTB.Text = "File Does Not Exist | Log Data To Create File";
                chart.Text = "Scope On";
            }
    
            if (File.Exists(logFile))
            {
                var lineCount = File.ReadLines(logFile).Count();//read text file line count to establish length for array
                if (lineCount < 2)
                {
                    viewLog.Text = "Play";
                    alertTB.ForeColor = Color.Red;
                    alertTB.Text = "File Exists | No Data Has Been Recorded";
                    chart.Text = "Scope On";
                }
    
                if (counter < lineCount && lineCount > 0)//if counter is less than lineCount keep reading lines
                {
                    line = File.ReadAllLines(logFile).Skip(counter).Take(lineCount).First();
    
                    string[] dataLog = line.Split(new[] { ',' }, StringSplitOptions.None);
                    //-----------------------------------------Handling my data 
                    counter++;
                }
                else
                {
                    counter = 0;
                    timer2.Enabled = false;
                }
            }
    

    This is the fix I arrived at, it allows editing the file or deleting the contents of the file. I get the line count before trying to load the file. I then use the counter to iterate through the lines. I can change the delay between the next line read based upon the timer tick interval, pause it, or stop it.