Franva
Franva

Reputation: 7077

How to present(not open) a very large file into an UI component(TextBox) quickly

Before talking about my question, I'd like to clarify that this is not a question asking about how to OPEN a large text file.

I have done it. It's a 150MB .txt file and I dump it into a dictionary object around 1 second. After this, I'd like to display it in an UI component.

I have tried to use TextBox, but until now the application windows hasn't shown up (it's been already 5 mins after I clicked the F5).....

So the question is what is the better UI component to display a large number of characters(I have 393300 elements in the dictionary object)

Thanks

Update:

 private void LoadTermCodes(TextBox tb)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            StreamReader sr = new StreamReader(@"xxx.txt");
            string line;
            while ((line = sr.ReadLine()) != null)
            {
                string[] colums = line.Split('\t');
                var id = colums[4];
                var diagnosisName = colums[7];

                if (dic.Keys.Contains(id))
                {
                    var temp = dic[id];
                    temp += "," + diagnosisName;
                    dic[id] = temp;
                }
                else
                {
                    dic.Add(id, diagnosisName);
                }

                //tb.Text += line + Environment.NewLine;
            }

            sw.Stop();
            long spentTime = sw.ElapsedMilliseconds;

            foreach (var element in dic)
            {
                tb.Text += element.Key + "\t" + element.Value + Environment.NewLine;
            }

            //tb.Text = "Eplased time (ms) = " + spentTime;
            MessageBox.Show("Jie shu le haha~~~ " + spentTime);
        }

Upvotes: 3

Views: 182

Answers (1)

Owen
Owen

Reputation: 501

The long running issue you're seeing is possibly due to how String are handled by the c# runtime. Since Strings are immutable what's happening every time you're calling + on them it's copying the String so far and the next small part into a new memory location and then returning that.

There's a good couple of articles by Eric Lippert here: Part 1 and Part 2 that explain it under the hood.

Instead, to stop all of this copying, you should use a StringBuilder. What this will do to your code is:

private void LoadTermCodes(TextBox tb)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    StreamReader sr = new StreamReader(@"xxx.txt");
    string line;

    // initialise the StringBuilder
    System.Text.StringBuilder outputBuilder = new System.Text.StringBuilder(String.Empty);
    while ((line = sr.ReadLine()) != null)
    {
        string[] colums = line.Split('\t');
        var id = colums[4];
        var diagnosisName = colums[7];

        if (dic.Keys.Contains(id))
        {
            var temp = dic[id];
            temp += "," + diagnosisName;
            dic[id] = temp;
        }
        else
        {
            dic.Add(id, diagnosisName);
        }
    }

    sw.Stop();
    long spentTime = sw.ElapsedMilliseconds;

    foreach (var element in dic)
    {
        // append a line to it, this will stop a lot of the copying
        outputBuilder.AppendLine(String.Format("{0}\t{1}", element.Key, element.Value));
    }

    // emit the text
    tb.Text += outputBuilder.ToString();

    MessageBox.Show("Jie shu le haha~~~ " + spentTime);
}

Upvotes: 4

Related Questions