Andrew Truckle
Andrew Truckle

Reputation: 19157

Adding progress bar monitoring for StreamReader?

I am writing a fairly simple windows form C# application in Visual Studio 2015. Here is one of my handlers:

private void button2_Click(object sender, EventArgs e)
{
    listBoxCodes.Items.Clear();
    listBoxDuplicates.Items.Clear();

    Cursor.Current = Cursors.WaitCursor;
    Application.DoEvents();

    progressBar.Value = 0;
    using (var reader = new StreamReader(textBoxGENIO.Text))
    {
        // progressBar is set for 5 unit intervals (from 0 to 100)

        // How can I show % complete reading the file?

        string line;
        while ((line = reader.ReadLine()) != null)
        {
            if(line.Length > 8 && line.Substring(0, 4) == "080,")
            {
                string strCode = line.Substring(4, 4);

                if (listBoxCodes.FindStringExact(strCode) == -1)
                    listBoxCodes.Items.Add(strCode);
                else
                    listBoxDuplicates.Items.Add(strCode);
            }
        }
    }

    Cursor.Current = Cursors.Default;
}

Now, I understand that I can read the file through once, to get the total number of lines, and then read the file through again, and do progress monitoring based on the percentage through the line count.

But I want to avoid reading the file twice because they can get very large.

Is there any way that I can use the file position / file size instead to establish the percentage complete?

I can't see any Position method in the StreamReader object.

Thank you.

Update: Currently looking at this question which may be the answer:

Tracking the position of the line of a streamreader

Update:

My calculations seem to be wrong:

private void button2_Click(object sender, EventArgs e)
{
    listBoxCodes.Items.Clear();
    listBoxDuplicates.Items.Clear();

    Cursor.Current = Cursors.WaitCursor;
    Application.DoEvents();

    int iLastPercentage = -1;

    progressBar.Value = 0;
    using (var reader = new StreamReader(textBoxGENIO.Text))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            // progressBar is set for 5 unit intervals (from 0 to 100)

            // How can I show % complete reading the file?
            int iPercentage = Convert.ToInt32(((double)reader.BaseStream.Length / 100.0) * (double)reader.BaseStream.Position);
            if (iLastPercentage == -1 || (iPercentage - iLastPercentage >= 5))
            {
                progressBar.PerformStep();
                iLastPercentage = iPercentage;
                Application.DoEvents();
            }

            if (line.Length > 8 && line.Substring(0, 4) == "080,")
            {
                string strCode = line.Substring(4, 4);

                if (listBoxCodes.FindStringExact(strCode) == -1)
                    listBoxCodes.Items.Add(strCode);
                else
                    listBoxDuplicates.Items.Add(strCode);
            }
        }
    }

    Cursor.Current = Cursors.Default;
}

}

Upvotes: 3

Views: 7978

Answers (2)

Pan Markosian
Pan Markosian

Reputation: 101

This is the correct way, you must typecast it to double

private void button_Load_Int_Click(object sender, EventArgs e)
    {
        Application.DoEvents();
        progressBar.Value = 0;
        using (StreamReader sr = new StreamReader(pathInt))
        {
            Stream baseStream = sr.BaseStream;
            long length = baseStream.Length;
            string line;
            while ((line = sr.ReadLine()) != null)
            {
                string strCode = line.Substring(4, 4);

                if (listBoxCodes.FindStringExact(strCode) == -1)
                    listBoxCodes.Items.Add(strCode);
                else
                    listBoxDuplicates.Items.Add(strCode)
                progressBar.Value = Convert.ToInt32((double)baseStream.Position / length * 100);
                Application.DoEvents();
            }
        }
    }

Upvotes: 4

Mango Wong
Mango Wong

Reputation: 649

See if below works for you:

private void button2_Click(object sender, EventArgs e)
{
    listBoxCodes.Items.Clear();
    listBoxDuplicates.Items.Clear();

    Cursor.Current = Cursors.WaitCursor;
    Application.DoEvents();

    progressBar.Value = 0;
    using (var reader = new StreamReader(textBoxGENIO.Text))
    {
        // progressBar is set for 5 unit intervals (from 0 to 100)

        // How can I show % complete reading the file?
        Stream baseStream = reader.BaseStream;
        long length = baseStream.Length;

        string line;
        while ((line = reader.ReadLine()) != null)
        {
            if(line.Length > 8 && line.Substring(0, 4) == "080,")
            {
                string strCode = line.Substring(4, 4);

                if (listBoxCodes.FindStringExact(strCode) == -1)
                    listBoxCodes.Items.Add(strCode);
                else
                    listBoxDuplicates.Items.Add(strCode);
            }

            progressBar.Value = baseStream.Position / length * 100;
            // Add code to update your progress bar UI
        }
    }

    Cursor.Current = Cursors.Default;
}

Upvotes: 4

Related Questions