File I/O in C# — Complete Guide
In this tutorial, you will learn about File I/O in C#. We cover key concepts, practical examples, and best practices to help you master this topic.
Hook
Every real-world application needs to persist data. Whether you are saving user preferences, processing log files, or importing data from an external source, file I/O is an essential skill. C# provides a rich set of classes in the System.IO namespace to handle files and directories with ease.
Learning Path
graph LR A[File I/O Basics] --> B[StreamReader StreamWriter] B --> C[File Directory Path] C --> D[Async I/O] D --> E[Binary Serialization] style A fill:#4a90d9,color:#fff style B fill:#4a90d9,color:#fff style C fill:#4a90d9,color:#fff style D fill:#4a90d9,color:#fff style E fill:#4a90d9,color:#fff
The File Class
The File class provides static methods for creating, copying, deleting, and moving files. It is the simplest way to perform basic file operations.
string path = "example.txt";
// Write all text (creates or overwrites)
File.WriteAllText(path, "Hello, C# File I/O!");
// Read all text
string content = File.ReadAllText(path);
Console.WriteLine(content);
// Append text
File.AppendAllText(path, "\nAppended line.");
// Check existence
bool exists = File.Exists(path);
Console.WriteLine($"File exists: {exists}");
// Delete
File.Delete(path);
Output:
Hello, C# File I/O!
File exists: True
StreamReader and StreamWriter
For more control, use StreamReader and StreamWriter. These classes read and write text line by line.
string path = "lines.txt";
// Writing lines
using (StreamWriter writer = new StreamWriter(path))
{
writer.WriteLine("First line");
writer.WriteLine("Second line");
writer.WriteLine("Third line");
}
// Reading lines
using (StreamReader reader = new StreamReader(path))
{
string? line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
Output:
First line
Second line
Third line
The using statement ensures the file handle is closed even if an exception occurs.
The Directory Class
Directory provides static methods for creating, deleting, and enumerating directories.
string dir = "MyFolder";
// Create directory
Directory.CreateDirectory(dir);
// Create a file inside
File.WriteAllText(Path.Combine(dir, "note.txt"), "Hello!");
// List files
string[] files = Directory.GetFiles(dir);
foreach (string file in files)
{
Console.WriteLine(Path.GetFileName(file));
}
// Delete directory recursively
Directory.Delete(dir, recursive: true);
Output:
note.txt
The Path Class
Path helps you manipulate file and directory paths safely across platforms.
string fullPath = Path.Combine("folder", "sub", "file.txt");
Console.WriteLine($"Combined: {fullPath}");
string ext = Path.GetExtension("document.pdf");
Console.WriteLine($"Extension: {ext}");
string name = Path.GetFileNameWithoutExtension("document.pdf");
Console.WriteLine($"Name: {name}");
string? dir = Path.GetDirectoryName("/home/user/file.txt");
Console.WriteLine($"Directory: {dir}");
string temp = Path.GetTempFileName();
Console.WriteLine($"Temp file: {temp}");
Output:
Combined: folder/sub/file.txt
Extension: .pdf
Name: document
Directory: /home/user/file.txt
Temp file: /tmp/tmpXXXXXX.tmp
Async File I/O
Modern C# applications should use async methods to avoid blocking threads during I/O operations.
async Task ReadFileAsync(string path)
{
using (StreamReader reader = new StreamReader(path))
{
string content = await reader.ReadToEndAsync();
Console.WriteLine(content);
}
}
async Task WriteFileAsync(string path, string content)
{
await File.WriteAllTextAsync(path, content);
Console.WriteLine("File written asynchronously.");
}
The async variants are available in .NET Core and .NET 5+ for all major File and stream methods.
Binary Files with BinaryReader and BinaryWriter
For non-text data, use BinaryWriter and BinaryReader.
string path = "data.bin";
using (BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create)))
{
writer.Write(42); // int
writer.Write(3.14); // double
writer.Write("Hello binary"); // string
}
using (BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open)))
{
int i = reader.ReadInt32();
double d = reader.ReadDouble();
string s = reader.ReadString();
Console.WriteLine($"{i}, {d}, {s}");
}
Output:
42, 3.14, Hello binary
File Security and Exceptions
Always handle exceptions when working with the file system.
try
{
string content = File.ReadAllText("nonexistent.txt");
}
catch (FileNotFoundException)
{
Console.WriteLine("File not found.");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("Access denied.");
}
catch (IOException ex)
{
Console.WriteLine($"I/O error: {ex.Message}");
}
Common Mistakes
Forgetting to dispose streams: Always wrap streams in
usingstatements or callDispose.Using relative paths without checking the working directory: Use
Path.GetFullPathorAppContext.BaseDirectoryto resolve paths.Ignoring encoding: Default encoding is UTF-8. Use
Encoding.UTF8explicitly when working with non-standard text.Blocking the UI thread with synchronous I/O: Always use async methods in GUI or web applications to avoid freezing.
Assuming files are closed immediately: Streams buffer writes; call
Flush()or ensure disposal to persist data.
Practice Questions
Write a method that reads a text file, counts the number of words, and returns the count.
Create a program that copies all
.txtfiles from one directory to another usingDirectory.EnumerateFiles.Implement a simple logger that appends timestamped messages to a log file using
StreamWriter.Challenge: Write a program that recursively lists all files in a directory tree with their sizes in a human-readable format.
FAQ
Mini Project: File Sorter
Create a console application that reads a text file containing one number per line, sorts them, and writes the sorted numbers to a new file. Include error handling for invalid lines and empty files.
using System;
string inputPath = "input.txt";
string outputPath = "sorted_output.txt";
// Generate sample data
File.WriteAllLines(inputPath, new[] { "42", "7", "19", "3", "88", "12" });
try
{
var numbers = new List<int>();
string[] lines = File.ReadAllLines(inputPath);
foreach (string line in lines)
{
if (int.TryParse(line.Trim(), out int num))
numbers.Add(num);
else
Console.WriteLine($"Skipping invalid line: {line}");
}
numbers.Sort();
File.WriteAllLines(outputPath, numbers.Select(n => n.ToString()));
Console.WriteLine($"Sorted {numbers.Count} numbers to {outputPath}");
Console.WriteLine(string.Join(", ", numbers));
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
Output:
Sorted 6 numbers to sorted_output.txt
3, 7, 12, 19, 42, 88
This project combines file reading, Parsing, sorting, and writing -- all core file I/O skills for your C# toolkit. The .NET base class library makes these operations straightforward and reliable.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro