Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read/Write text file progressbar in C#

I have a function which reads a big text file,splits a part(from a given start and end),and save the splitted data into another text file.since the file is too big,i need to add a progressbar when reading the stream and another one when writing the splitted text into the other file.Ps.start and end are given datetime!!

using (StreamReader sr = new StreamReader(file,System.Text.Encoding.ASCII))
{
    while (sr.EndOfStream == false)
    {
        line = sr.ReadLine();

        if (line.IndexOf(start) != -1)
        {
            using (StreamWriter sw = new StreamWriter(DateTime.Now.ToString().Replace("/", "-").Replace(":", "-") + "cut"))
            {
                sw.WriteLine(line);
                while (sr.EndOfStream == false && line.IndexOf(end) == -1)
                {
                    line = sr.ReadLine();
                    sw.WriteLine(line);
                }
            }

            richTextBox1.Text += "done ..." + "\n";
            break;
        }
    }
}
like image 542
user1096252 Avatar asked Dec 28 '22 09:12

user1096252


1 Answers

The first thing to do would be to work out how long the file is using FileInfo,

http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx

FileInfo fileInfo = new FileInfo(file);
long length = fileInfo.Length;

I would suggest you do it like this,

private long currentPosition = 0;

private void UpdateProgressBar(int lineLength)
{
    currentPosition += line.Count; // or plus 2 if you need to take into account carriage return
    progressBar.Value = (int)(((decimal)currentPosition / (decimal)length) * (decimal)100);
}

private void CopyFile()
{
    progressBar.Minimum = 0;
    progressBar.Maximum = 100;

    currentPosition = 0;

    using (StreamReader sr = new StreamReader(file,System.Text.Encoding.ASCII))
    {
        while (sr.EndOfStream == false)
        {
            line = sr.ReadLine();
            UpdateProgressBar(line.Length);

            if (line.IndexOf(start) != -1)
            {
                using (StreamWriter sw = new StreamWriter(DateTime.Now.ToString().Replace("/", "-").Replace(":", "-") + "cut"))
                {
                    sw.WriteLine(line);
                    while (sr.EndOfStream == false && line.IndexOf(end) == -1)
                    {
                        line = sr.ReadLine();
                        UpdateProgressBar(line.Length);
                        sw.WriteLine(line);
                    }
                }

                richTextBox1.Text += "done ..." + "\n";
                break;
            }
        }
    }
}

Which is calculating the percentage of the file that has been read and setting the progress bar to that value. Then you don't have to worry about whether the length is a long, and the progress bar uses int.

If you don't want to truncate the value then do this (casting to an int above will always truncate the decimals, and thus round down),

progressBar.Value = (int)Math.Round(((decimal)currentPosition / (decimal)length) * (decimal)100), 0);

Is this on a background thread? Don't forget that you will have to call this.Invoke to update the progress bar or else you will get a cross thread exception.

like image 71
peter Avatar answered Jan 09 '23 12:01

peter