C#: How to read a file? | Fastest way to read a file in C#

By Josip Miskovic
A thumbnail showing C# exceptions code.

How to read a file in C#?

Here are the most common ways to read a file in C#:

ReadAllText

To read a file in C#, use the System.IO.File.ReadAllText method. The ReadAllText method reads the contents of a file and returns it as a string. Here is an example of how to use it:

C#
string fileData = System.IO.File.ReadAllText(@"C:\example.txt");

The code above reads the contents of the file located at C:\example.txt and stores it as a string.

ReadAllLines

To read the contents of a file into a string array, use the ReadAllLines method.

C#
string[] lines = System.IO.File.ReadAllLines(@"C:\example.txt");

Each element in the array represents a line in the file.

ReadLines

The System.IO.File.ReadLines method reads the lines of a file and returns an IEnumerable<string> that can be used to iterate over the lines of the file. The lines of the file are not read into memory until they are enumerated.

Here is an example of how to use the ReadLines method to iterate over the lines of a file:

C#
string filePath = @"C:\example.txt";
foreach (string line in File.ReadLines(filePath))
{
    Console.WriteLine(line);
}

The code above reads the file one line at a time and print each line to the console. The lines of the file are not read into memory until they are enumerated, so this can be more memory-efficient than reading the entire file into a string or string array.

StreamReader

If you have a large file, you can use StreamReader to read one line at a time, or to read in chunks.

ReadLine

Here is an example of how to use the StreamReader to read line-by-line:

C#
using (StreamReader reader = new StreamReader(@"C:\example.txt"))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        Console.WriteLine(line);
    }
}

Under the hood, ReadLines uses the StreamReader and the ReadLine method, similarly to the code above. Unless you want to perform more advanced chunking using the ReadLines method is more convenient approach.

ReadBlock

To read a file in chunks using a StreamReader, use the ReadBlock method, which reads a specified number of characters from the stream into a character array, starting at a specified index. H

Here is an example of how to use the ReadBlock method to read a file in chunks:

C#
using (StreamReader reader = new StreamReader(@"C:\example.txt"))
{
    char[] buffer = new char[1024];
    int numRead;
    while ((numRead = reader.ReadBlock(buffer, 0, buffer.Length)) > 0)
    {
        // Do something with the chunk of characters
    }
}

The code above reads the file in blocks of 1024 characters at a time. You can adjust the size of the buffer to control the size of the chunks that are read.

C# Read File Performance

It's crucial to consider the performance of you application when reading a file because loading large files into memory can cause your system to crash due to memory exhaustion.

For example, when you use the ReadAllText method to read a file, the entire contents of the file are read into a single string that is kept in memory.

For example, if the file is 1 MB in size, then the ReadAllText method will read the file into a string that is also 1 MB in length, which will use at least 1 MB of memory.

Benchmark: File Reading

To measure which method of reading a file is the most efficient, I ran tests loading a large 32 MB file.

The table below shows performance benchmarks measured using BenchmarkDotNet library:

MethodMeanErrorStdDevGen 0Gen 1Gen 2Allocated
ReadAllText104.15 ms2.695 ms3.504 ms15200.00006400.00002600.0000126 MB
ReadAllLines232.26 ms3.982 ms5.316 ms14666.66675666.66672000.000091 MB
StreamReader91.13 ms1.465 ms1.956 ms20000.0000--80 MB
ReadLines92.95 ms1.036 ms1.272 ms20000.0000--80 MB

Using the StreamReader or ReadLines method of reading a file line-by-line is the most efficient in terms of both speed and memory allocation.

However, ReadAllText and ReadAllLines method are both more convenient options if you need to access to the entire data rather than line-by-line.

Get full code used for performance metrics

Performance metrics conclusion:

  • If you have a large file, try to use the StreamReader to preserve the memory.
    • If you just want to iterate line-by-line, use ReadLines.
  • If memory allocation is not an issue, use ReadAllText or ReadAllLines for code simplicity.

→ Also read: Stream to File in C#

What is considered a large file to read into memory?

There is no precise definition of what is considered a "large file," as it depends on the available memory and processing power of the system that is reading the file. In general, a file is considered large if it is too large to be efficiently processed or stored in memory all at once.

When working with large files, it's important to consider the memory and processing requirements of your code and to choose the most appropriate techniques for reading and processing the file. Techniques like reading the file in chunks or streaming the data can help to reduce the memory usage and improve the performance of your code.

How to read a CSV file in C#?

To read a CSV (comma-separated values) file in C#, you can use a StreamReader and split each line of the file into an array of values using the string.Split method:

C#
using (StreamReader reader = new StreamReader(@"C:\example.csv"))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        string[] values = line.Split(',');
        // Do something with the values
    }
}

How to check if a file exists before reading it in C#?

To check if a file exists before reading it in C#, you can use the System.IO.File.Exists method:

C#
string filePath = @"C:\example\file.txt";
if (File.Exists(filePath))
{
    string fileContents = File.ReadAllText(filePath);
    // Do something with the file contents
}
else
{
    Console.WriteLine("The file does not exist.");
}

If you try to read a file that doesn't exist, you'll get exceptions of type FileNotFoundException or DirectoryNotFoundException. As an alternative to checking if file exists, you can use exception filters to catch the mentioned exceptions.

Appendix

Video explanation

Full code used for performance metrics

Here's the DotNetBenchmark code I've used to run the file reading performance test:

C#
using BenchmarkDotNet.Attributes;

[MemoryDiagnoser]
[SimpleJob(launchCount: 1, warmupCount: 1, targetCount: 25)]
public class FileReadingBenchmark
{
    // Set the path to the file you want to read
    private string filePath = @"C:\Users\j\Downloads\test\file.txt";

    // Add a benchmark method for each method you want to test
    [Benchmark]
    public void ReadAllText()
    {
        string fileContents = File.ReadAllText(filePath);
    }

    [Benchmark]
    public void ReadAllLines()
    {
        string[] lines = File.ReadAllLines(filePath);
    }

    [Benchmark]
    public void StreamReader()
    {
        using (StreamReader reader = new StreamReader(filePath))
        {
            string? line;
            while ((line = reader.ReadLine()) != null)
            {
                //
            }
        }
    }

    [Benchmark]
    public void ReadLines()
    {
        foreach (string line in File.ReadLines(filePath))
        {
            //
        }
    }
}
Josip Miskovic
About Josip

Josip Miskovic is a software developer at Americaneagle.com. Josip has 10+ years in experience in developing web applications, mobile apps, and games.

Read more posts →
Published on:
Download Free Software Developer Career Guide

I've used these principles to increase my earnings by 63% in two years. So can you.

Dive into my 7 actionable steps to elevate your career.