Loading...

File IO and Stream API in C#

Learn file input/output and Stream API in C#, including reading, writing, and managing file data efficiently.

In C#, File IO (Input/Output) and the Stream API are the core mechanisms for reading and writing files. Files can be processed as text or binary, and using the stream approach allows efficient handling of large data without loading it all into memory. In this article, we will cover File, FileInfo, StreamReader/StreamWriter, FileStream, and BinaryReader/BinaryWriter with comprehensive examples.


File Class

The File class provides static methods for quick file operations. Commonly used methods include: WriteAllText, ReadAllText, AppendAllText, Exists, Delete.


using System;
using System.IO;

// Write to a file
File.WriteAllText("demo.txt", "Hello World!");

// Read from a file
string content = File.ReadAllText("demo.txt");
Console.WriteLine(content);

// Check if file exists
if (File.Exists("demo.txt"))
    Console.WriteLine("File exists.");

// Append to a file
File.AppendAllText("demo.txt", "\nNew line added.");

// Delete a file
File.Delete("temp.txt");

FileInfo Class

FileInfo is instance-based and provides detailed information and operations on files. It contains methods such as Exists, Create, Delete, CopyTo, and MoveTo.


var info = new FileInfo("example.txt");

// Create file if it doesn’t exist
if (!info.Exists)
{
    using (var sw = info.CreateText())
        sw.WriteLine("This file was created using FileInfo.Create.");
}

// Print file information
Console.WriteLine($"Name: {info.Name}, Size: {info.Length} bytes, Path: {info.FullName}");

// Copy file
info.CopyTo("example_copy.txt", overwrite: true);

// Move file
info.MoveTo("new_example.txt");

// Delete file
var toDelete = new FileInfo("new_example.txt");
if (toDelete.Exists)
    toDelete.Delete();

StreamReader and StreamWriter

StreamReader and StreamWriter are used for text-based file operations. When used with a using block, the file is automatically closed after the operation.


// Write to a text file
using (var writer = new StreamWriter("text.txt"))
{
    writer.WriteLine("Line 1");
    writer.WriteLine("Line 2");
}

// Read from a text file
using (var reader = new StreamReader("text.txt"))
{
    string line;
    while ((line = reader.ReadLine()) != null)
        Console.WriteLine(line);
}

// Output:
// Line 1
// Line 2

FileStream

FileStream allows reading/writing files at the byte level. It is especially useful when working with large files such as images or videos.


// Write bytes to a file
byte[] data = { 72, 101, 108, 108, 111 }; // "Hello"
using (var fs = new FileStream("data.bin", FileMode.Create))
{
    fs.Write(data, 0, data.Length);
}

// Read bytes from a file
using (var fs = new FileStream("data.bin", FileMode.Open))
{
    int b;
    while ((b = fs.ReadByte()) != -1)
        Console.Write((char)b);
}
// Output: Hello

BinaryReader and BinaryWriter

BinaryReader and BinaryWriter allow writing/reading primitive data types (int, double, string, etc.) directly into/from a binary stream.


using (var bw = new BinaryWriter(File.Open("numbers.dat", FileMode.Create)))
{
    bw.Write(42);
    bw.Write(3.14);
    bw.Write("Hello");
}

using (var br = new BinaryReader(File.Open("numbers.dat", FileMode.Open)))
{
    int i = br.ReadInt32();
    double d = br.ReadDouble();
    string s = br.ReadString();

    Console.WriteLine($"{i}, {d}, {s}");
}
// Output: 42, 3.14, Hello

Sample Application: Log File Management

In the following example, application logs are written to a file using StreamWriter, then read back with StreamReader. Additionally, FileInfo is used to check if the file exists and create it if necessary.


public class Logger
{
    private readonly FileInfo _file = new FileInfo("app.log");

    public void Log(string message)
    {
        if (!_file.Exists)
            using (var created = _file.CreateText())
                created.WriteLine("Log file created.");

        using (var sw = new StreamWriter(_file.FullName, append: true))
            sw.WriteLine($"{DateTime.Now}: {message}");
    }

    public void ShowLogs()
    {
        if (_file.Exists)
        {
            using (var sr = new StreamReader(_file.FullName))
                Console.WriteLine(sr.ReadToEnd());
        }
        else
        {
            Console.WriteLine("Log file not found.");
        }
    }

    public void ClearLogs()
    {
        if (_file.Exists)
            _file.Delete();
    }
}

class Program
{
    static void Main()
    {
        var logger = new Logger();
        logger.Log("Application started.");
        logger.Log("An error occurred!");
        logger.ShowLogs();
        logger.ClearLogs();
    }
}

// Example output:
// 09/19/2025 12:10:05: Application started.
// 09/19/2025 12:10:05: An error occurred!

TL;DR

  • File: Static file operations (WriteAllText, ReadAllText, AppendAllText, Exists, Delete).
  • FileInfo: Instance-based file operations (Create, CopyTo, MoveTo, Delete, Exists).
  • StreamReader/StreamWriter: Text-based file read/write.
  • FileStream: Byte-level access, suitable for large files.
  • BinaryReader/BinaryWriter: Read/write primitive types in binary format.
  • Stream API enables efficient processing of large files without loading them entirely into memory.

Related Articles