C# File Handling Explained: Read, Write, Copy and Manage Files

File handling is a common requirement in C# applications. The .NET platform provides several APIs for creating, reading, writing, copying, moving, and deleting files and directories.

What is File Handling in C#?

File handling allows an application to interact with files stored on a computer or other accessible storage. C# provides convenient APIs through the System.IO namespace.

CSHARP
using System.IO;

string path = "data.txt";

File.WriteAllText(path, "Hello C#");

Creating and Writing a File

File.WriteAllText creates a file if it does not exist and writes the specified text. If the file already exists, its previous contents are replaced.

CSHARP
string path = "message.txt";

File.WriteAllText(path, "Welcome to C# file handling!");

Appending Text to a File

AppendAllText adds content to the end of an existing file without replacing its current contents.

CSHARP
File.AppendAllText(
    "message.txt",
    Environment.NewLine + "New message"
);

Reading an Entire File

ReadAllText reads the complete contents of a text file and returns them as a string.

CSHARP
string content = File.ReadAllText("message.txt");

Console.WriteLine(content);

Reading File Lines

ReadAllLines reads a text file and returns its contents as an array of strings, with each element representing a line.

CSHARP
string[] lines = File.ReadAllLines("data.txt");

foreach (string line in lines)
{
    Console.WriteLine(line);
}

Checking Whether a File Exists

File.Exists can be used to determine whether a file is available at a specified path.

CSHARP
string path = "data.txt";

if (File.Exists(path))
{
    Console.WriteLine("File exists");
}
else
{
    Console.WriteLine("File not found");
}

Copying a File

File.Copy creates a copy of a file at another location. The overwrite option controls whether an existing destination file can be replaced.

CSHARP
File.Copy(
    "data.txt",
    "backup.txt",
    overwrite: true
);

Moving a File

File.Move changes a file's location and can also be used to rename a file.

CSHARP
File.Move(
    "old-name.txt",
    "new-name.txt",
    overwrite: true
);

Deleting a File

File.Delete removes a file. It is good practice to check whether the file exists when application logic requires that distinction.

CSHARP
if (File.Exists("temp.txt"))
{
    File.Delete("temp.txt");
}

Working with Directories

The Directory class provides methods for creating, checking, listing, moving, and deleting directories.

CSHARP
string folder = "Reports";

if (!Directory.Exists(folder))
{
    Directory.CreateDirectory(folder);
}

string[] files = Directory.GetFiles(folder);

Path Class

The Path class provides platform-aware methods for combining and inspecting file and directory paths.

CSHARP
string folder = "Reports";
string fileName = "report.txt";

string path = Path.Combine(folder, fileName);

Console.WriteLine(path);

Getting File Information

FileInfo provides an object-oriented way to inspect and manage a specific file, including its size, name, location, and timestamps.

CSHARP
FileInfo file = new FileInfo("data.txt");

Console.WriteLine(file.Name);
Console.WriteLine(file.Length);
Console.WriteLine(file.FullName);

StreamReader

StreamReader is useful when a file needs to be read progressively rather than loaded entirely into memory.

CSHARP
using StreamReader reader = new StreamReader("large-data.txt");

string? line;

while ((line = reader.ReadLine()) != null)
{
    Console.WriteLine(line);
}

StreamWriter

StreamWriter allows text to be written to a file progressively, which can be useful for larger files or continuous output.

CSHARP
using StreamWriter writer = new StreamWriter("log.txt");

writer.WriteLine("Application started");
writer.WriteLine("Processing data");
writer.WriteLine("Application finished");

Asynchronous File Operations

Modern .NET provides asynchronous file APIs that are useful when file operations may take enough time to affect application responsiveness.

CSHARP
string content = await File.ReadAllTextAsync("data.txt");

await File.WriteAllTextAsync(
    "output.txt",
    content
);

File Handling Comparison

APIPurposeTypical Use
FileStatic file operationsSimple read/write/copy/delete
FileInfoObject-oriented file operationsRepeated operations on one file
DirectoryDirectory managementCreate/list/delete folders
PathPath manipulationBuild safe file paths
StreamReaderRead text progressivelyLarge text files
StreamWriterWrite text progressivelyLogs and large output

Handling File Exceptions

File operations can fail because of missing files, invalid paths, permissions, locks, or other environmental conditions. Applications should handle expected failures appropriately.

CSHARP
try
{
    string content = File.ReadAllText("data.txt");
    Console.WriteLine(content);
}
catch (FileNotFoundException)
{
    Console.WriteLine("The file was not found.");
}
catch (UnauthorizedAccessException)
{
    Console.WriteLine("Access to the file was denied.");
}

Common File Handling Mistakes

  • Using hard-coded absolute paths unnecessarily
  • Ignoring file permissions
  • Loading very large files entirely into memory
  • Forgetting to dispose streams
  • Overwriting important files without confirmation
  • Assuming a file always exists

File Handling Best Practices

  • Use Path.Combine instead of manually concatenating paths
  • Prefer using statements for disposable streams
  • Use asynchronous APIs for appropriate I/O workloads
  • Validate paths and required directories
  • Handle expected I/O exceptions
  • Avoid loading huge files into memory unnecessarily
  • Use appropriate file access permissions

Real-World Applications

  • Application logging
  • Configuration files
  • CSV and text processing
  • Report generation
  • File uploads and downloads
  • Backup systems
  • Data import and export

Practice Exercises

  • Create and write a text file
  • Read a file line by line
  • Append new log entries
  • Copy a file into a backup directory
  • Create a directory if it does not exist
  • Build a simple file search utility
  • Read and write a file asynchronously

Conclusion

C# provides a complete set of APIs for working with files, directories, paths, and streams. Understanding these tools allows developers to build applications that safely and efficiently manage persistent data.

Note: Note: Use the simplest appropriate file API for small operations, streams for larger workloads, and asynchronous APIs when non-blocking file I/O is beneficial.