Home > Net >  How can I utilize File.ReadLines instead of File.ReadAllLines in C# for this purpose
How can I utilize File.ReadLines instead of File.ReadAllLines in C# for this purpose

Time:07-26

Hi I am trying to make a program which ; takes an input txt file then shows its lines in reverse order

I was using File.ReadAllLines so I get a array of strings then I used indexes of the strings and used for loop to reverse the order.

But I did some research and found the File.ReadAllLines is not good for very long txt files so they say I should use File.ReadLines.

But I couldn't understand how to access the lines indexes as I did in string array

My working code is below ( which is written by using File.ReadAllLines) I want to do this with File.ReadLines How can I do this how can I access indexes if I use ReadlLines

    private void button1_Click(object sender, EventArgs e)
    {
        openFileDialog1 = new OpenFileDialog();
        openFileDialog1.Filter = "Txt Files Only |*.txt";
        openFileDialog1.InitialDirectory = @"C:\";
        openFileDialog1.Title = "Load Log File";           
        openFileDialog1.ShowDialog();
        textBox1.Text = openFileDialog1.FileName;
        checkBox1.Checked = true;

    }

    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {

    }

    private void button2_Click(object sender, EventArgs e)
    {
        textBox1.Clear();
        checkBox1.Visible = false;
        button1.Visible = false;
        textBox1.Multiline = true;
        textBox1.Height = 200;
        textBox1.Width = 600;
        button2.Visible = false;
        textBox1.ScrollBars = ScrollBars.Vertical;
        string[] lines = File.ReadAllLines(openFileDialog1.FileName);
        int n = lines.Length;
        for (int i = 0; n > i; n--)
        {
            textBox1.Text  = lines[n - 1]   Environment.NewLine;
        }

    }

CodePudding user response:

To reverse the lines, you need to load all of them into memory anyway (unless you read from the bottom), so File.ReadAllLines is the correct choice.

But I couldn't understand how to access the lines indexes as I did in string array

You can't. File.ReadLines returns an IEnumerable<String>. IEnumerables can't be indexed. You could call ToArray or ToList to transform it to an array or list. In alternative, you can use ElementAt on the IEnumberable to get the value at the specified index. This is very inefficient, tho.

Summary: Stick to File.ReadAllLines

CodePudding user response:

You could use

IEnumerable<string> lines = File.ReadLines(openFileDialog1.FileName);
foreach (string line in lines.Reverse()) {
    ...
}

However, you won't get any performance benefit in this case, as the Reverse() operation will have to buffer all the lines. And this is precisely what ReadLines avoids doing by reading the lines lazily as you are looping through them.

Using ReadAllLines and a reverse for-loop is better in this case. But you can get a performance benefit by using a StringBuilder:

var sb = new StringBuilder();
string[] lines = File.ReadAllLines(openFileDialog1.FileName);
for (int i = lines.Length - 1; i >= 0; i--)
{
    sb.AppendLine(lines[i]);
}
textBox1.Text = sb.ToString();

The reason for this is that creating a string with repeated = operations will create a new, lager string each time and copy the old value into the new one.

See also: Use Visual C# to improve string concatenation performance.

To increase the speed further, you could calculate the size of the resulting text in advance and use it to initialize the StringBuilder with an optimal buffer size.

string[] lines = File.ReadAllLines(openFileDialog1.FileName);
var sb = new StringBuilder(lines.Sum(s => s.Length   2));

Note: You can expand the forr code snippet in Visual Studio to get a reverse for loop.

CodePudding user response:

I don't think what you are trying to do is possible with File.ReadLines, since it returns an IEnumerable which is in this case implemented as a ReadLinesIterator. The iterator is only able to read one line at a time going forward. Anything that requires knowledge about all the lines (reversing them, counting them...) cannot be done without iterating through all lines first.

You could find lower-level approaches to do that, but it might be tricky. Anyway, since you are displaying all the lines inside a textbox, you are keeping all the file's content in memory anyway. Looking for a more efficient way to read the file doesn't seem really useful in this case.

  • Related