Skip to main content

Optimal ways to read a files line-by-line or byte-by-byte in C#.

using System;
using System.Text;
using System.IO;

/// <summary>
/// Method 1 ReadToEnd()...
///
/// However here we reach a problem: the entire contents of the text
/// file is being read all at once. If the text file is small or we do
/// not need to do anything with individual lines then that's fine.
///
/// However, say we want to append a line number to each line we read.
/// In order to do so, we have to use the StringReader class to read
/// through the entire string and count the number of lines. Then we
/// can go back and go through the lines individually.
/// </summary>
private static string ReadTextFile1(string path)
{
    //Method 1

    //Load the file contents
    StreamReader textFile = new StreamReader(path);
    string fileContents = textFile.ReadToEnd();
    textFile.Close();

    //Find the number of lines
    StringReader reader = new StringReader(fileContents);
    int lineCount = 0;
    while (reader.ReadLine() != null)
    {
        lineCount++;
    }
    lineCount--;

    // Now read the file line by line
    reader = new StringReader(fileContents);
    string outputText = "";
    for (int i = 0; i <= lineCount; i++)
    {
        outputText += reader.ReadLine() + Environment.NewLine;
    }
    // This may seem redudant, but here is where you would do any
    // line-by-line processing. In this case we do nothing so it
    // seems uneccessary.

    return outputText;
}

/// <summary>
/// Method 2 Read Bytes
///
/// There is a much better way to read a text file in C#. This method
/// not only allows you to read a text file by lines, it allows you to do
/// so the first time it's being read, giving us the ability to track the
/// progress.
///
/// First we load the file's content in the form of bytes into a byte[]
/// array. For this example I read all the content at once, if you want
/// to read individual bytes at a time, use the function ReadByte.
///
/// Then, once we have all the bytes stored in an array, we need to go
/// through the bytes and find the end of the lines. To do so, we are
/// looking two bytes in a row: 13 and 10. In a Windows OS system,
/// the bytes 13-10 mark the end of a line (vbCrLf in Visual Basic).
private static string ReadTextFile2(string path)
{
    //Method 2

    //Load the file contents
    FileStream textFile = new FileStream(path, FileMode.Open);
    byte[] buffer = new byte[textFile.Length];
    textFile.Read(buffer, 0, buffer.Length);

    //Find the number of lines
    //Remember the char value for the end of a line is 13 + 10
    int lineCount = 0;
    for (int i = 0; i < buffer.Length; i++)
    {
        if (buffer[i] == 13)
        {
            if (i + 1 < buffer.Length && buffer[i + 1] == 10)
            {
                lineCount++;
            }
        }
    }

    //Now read the file line by line
    StringReader reader = new StringReader(Encoding.ASCII.GetString(buffer));
    string outputText = "";
    for (int i = 0; i <= lineCount; i++)
    {
        outputText += reader.ReadLine() + Environment.NewLine;
    }
    // This may seem redudant, but here is where you would do any
    // line-by-line processing. In this case we do nothing so it
    // seems uneccessary.

    return outputText;
    // If you rather just return the string straight away, use
    // return Encoding.ASCII.GetString(buffer);
}