File Handling in C#

File handling in C# is the set of techniques used to create, read, write, append, copy, move, and delete files and directories. It is a core part of real-world programming because many applications need to work with text files, logs, configuration files, reports, images, uploads, exports, and persisted data.

In .NET, file handling is mainly provided through namespaces such as System.IO. The platform offers both high-level convenience methods and lower-level stream-based APIs, so developers can choose the right level of control depending on the task.

Understanding file handling properly means more than memorizing a few methods. It also means knowing when to use simple helpers like File.ReadAllText(), when to use streams, how to clean up resources safely, how to work with paths, and how to handle file-related exceptions without creating fragile code.


What Is File Handling in C#?

File handling in C# refers to operations performed on files and directories through the .NET I/O APIs. These operations include reading existing files, writing new files, appending data, moving files, checking whether files exist, and traversing folders.

This area is important because files are one of the simplest and most common ways to store or exchange data between programs, users, and systems.

Namespaces Used for File Handling

The most important namespace for file handling in C# is System.IO.

using System.IO;

Types such as File, FileInfo, Directory, DirectoryInfo, StreamReader, StreamWriter, FileStream, and Path are available from this namespace.

File vs FileInfo in C#

C# gives you both static helper classes and object-based APIs for file operations. File provides static methods for common tasks, while FileInfo provides an instance-oriented approach.

TypeStyleTypical Use
FileStatic helper methodsQuick common file operations
FileInfoObject-basedWhen file metadata and repeated file operations are needed

Both are valid. For many everyday cases, File is simpler. When you want an object representing the file and its metadata, FileInfo can feel cleaner.

Reading a Text File in C#

The easiest way to read an entire text file is with File.ReadAllText().

string content = File.ReadAllText("data.txt");
Console.WriteLine(content);

This is convenient when the file is reasonably small and you need the full content at once.

If you want to read all lines into a string array, you can use File.ReadAllLines().

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

Writing a Text File in C#

To write text content into a file, use File.WriteAllText().

File.WriteAllText("report.txt", "Hello from C# file handling");

If the file already exists, this method overwrites it. If the file does not exist, it creates it.

To write multiple lines, File.WriteAllLines() is often convenient.

string[] reportLines = { "Line 1", "Line 2", "Line 3" };
File.WriteAllLines("report.txt", reportLines);

Appending to a File

If you want to add new content without overwriting the existing file, use append operations.

File.AppendAllText("log.txt", "New log entry\n");

Appending is common for logs, audit trails, simple exports, and incremental reports.

Checking Whether a File Exists

Before reading or writing in certain workflows, you may want to check whether the file exists.

if (File.Exists("data.txt"))
{
    Console.WriteLine("File found");
}

This is useful, but remember that file state can still change between the existence check and the actual file operation. Good production code still needs exception handling around the real operation.

Copying, Moving, and Deleting Files

File handling also includes file management operations such as copy, move, and delete.

File.Copy("source.txt", "backup.txt", overwrite: true);
File.Move("oldname.txt", "newname.txt");
File.Delete("temp.txt");

These operations are common in imports, exports, backup jobs, file-renaming utilities, and cleanup workflows.

Working with Directories

Directory operations are handled by the Directory and DirectoryInfo types.

Directory.CreateDirectory("Reports");
bool exists = Directory.Exists("Reports");
string[] files = Directory.GetFiles("Reports");

Directory handling matters whenever your program works with folder structures, uploads, exports, archives, or recursive scans.

Path Handling in C#

The Path class helps build and inspect file paths safely without manually concatenating path separators.

string filePath = Path.Combine("Reports", "summary.txt");
string extension = Path.GetExtension(filePath);
string fileName = Path.GetFileName(filePath);

Using Path.Combine() is better than hardcoding slashes because it makes the code more portable and less error-prone.

StreamReader and StreamWriter

When you want more control than the one-line helper methods provide, StreamReader and StreamWriter are common choices for text-based file operations.

using (StreamReader reader = new StreamReader("data.txt"))
{
    string content = reader.ReadToEnd();
    Console.WriteLine(content);
}

using (StreamWriter writer = new StreamWriter("output.txt"))
{
    writer.WriteLine("Hello from StreamWriter");
}

These APIs are useful when reading or writing progressively instead of loading the entire file content with one helper call.

FileStream in C#

FileStream gives lower-level control over file access. It is often used when working with binary data, manual buffering, or situations where specific file modes and access rules matter.

using FileStream stream = new FileStream(
    "data.bin",
    FileMode.OpenOrCreate,
    FileAccess.ReadWrite,
    FileShare.None);

This is a more advanced API, but it is important because many higher-level I/O types are built on top of stream-based operations.

Text Files vs Binary Files

Text files store human-readable character data, while binary files store raw bytes. The correct approach depends on the file format and the kind of data the program works with.

TypeTypical ContentCommon APIs
Text fileReadable text, config, CSV, logsFile.ReadAllText, StreamReader
Binary fileImages, raw bytes, custom binary dataFileStream, byte arrays

Choosing the wrong approach can corrupt data or make file content unreadable.

Async File Handling in C#

Modern applications often use asynchronous file APIs to avoid blocking threads during I/O-heavy work. This is especially important in web applications, UI apps, and scalable services.

string content = await File.ReadAllTextAsync("data.txt");
await File.WriteAllTextAsync("output.txt", content);

Async file APIs improve responsiveness when the application should continue handling other work while waiting for storage operations to complete.

Exception Handling in File Operations

File handling is full of real-world failure conditions. The file may not exist, the path may be invalid, the process may lack permission, or another process may already be using the file.

try
{
    string content = File.ReadAllText("missing.txt");
}
catch (FileNotFoundException ex)
{
    Console.WriteLine("File not found");
}
catch (UnauthorizedAccessException ex)
{
    Console.WriteLine("Access denied");
}
catch (IOException ex)
{
    Console.WriteLine("General I/O error");
}

This is a good reminder that file handling is not only about methods. It is also about safe error handling and realistic recovery paths.

using and Resource Cleanup

Types such as StreamReader, StreamWriter, and FileStream should be disposed properly. The using statement or declaration makes this safer and cleaner.

using StreamWriter writer = new StreamWriter("log.txt");
writer.WriteLine("Application started");

This ensures the resource is released even if an exception occurs later in the method.

Common File Modes in C#

When using FileStream, file modes control how the file should be opened.

FileModeMeaning
CreateCreate a new file or overwrite existing
CreateNewCreate a new file, fail if it exists
OpenOpen an existing file
OpenOrCreateOpen if it exists, otherwise create
AppendOpen and write at the end
TruncateOpen and clear existing content

These modes matter when the exact file lifecycle is important and you do not want helper methods hiding the behavior.

Common Mistakes with File Handling

  • Concatenating file paths manually instead of using Path.Combine().
  • Forgetting to dispose streams properly.
  • Reading entire huge files into memory when streaming would be safer.
  • Ignoring file-related exceptions and assuming files always exist.
  • Using sync file APIs in responsiveness-critical paths when async I/O would be better.

These mistakes can cause resource leaks, performance problems, portability issues, and unpredictable runtime failures.

Best Practices for File Handling in C#

  • Use high-level helpers like File.ReadAllText() for simple small-file tasks.
  • Use streams when you need progressive reading, binary handling, or more control.
  • Always dispose stream-based resources with using.
  • Use Path.Combine() for safe path construction.
  • Handle realistic I/O exceptions instead of assuming file operations always succeed.
  • Use async file APIs when scalability or responsiveness matters.

File Handling in Real Applications

In real applications, file handling appears in log writing, CSV import and export, report generation, configuration management, image uploads, archive processing, and document workflows. It is a practical topic because almost every business system needs to move data in or out of files at some point.

That is why file handling deserves careful understanding. It sits at the intersection of storage, performance, user workflows, and reliability.

File Handling Interview Points

For interviews, remember the difference between File and FileInfo, between Directory and DirectoryInfo, and between high-level text helpers and stream-based APIs. You should know why using is important, how to handle common I/O exceptions, and when async file methods are useful.

A stronger answer also mentions path safety, file modes, and the practical difference between text files and binary files.

FAQs on File Handling in C#

What is file handling in C#?

File handling in C# refers to reading, writing, creating, appending, copying, moving, deleting, and organizing files and directories through the .NET I/O APIs.

What namespace is used for file handling in C#?

The main namespace is System.IO.

What is the difference between File and FileInfo in C#?

File offers static helper methods for common tasks, while FileInfo provides an object-based approach with file metadata and instance-style operations.

Why should I use using with file streams?

The using pattern ensures streams and similar resources are disposed properly, even if an exception occurs.

FileInfo and DirectoryInfo for Metadata

When you need metadata such as file size, creation time, last write time, or folder information, the FileInfo and DirectoryInfo types are useful.

FileInfo info = new FileInfo("report.txt");
Console.WriteLine(info.Length);
Console.WriteLine(info.LastWriteTime);

This object-oriented style can be more convenient when the code needs both metadata and operations on the same file or directory.

Reading Large Files Safely

For small files, helper methods like ReadAllText() are fine. For large files, reading everything into memory at once may be wasteful or risky. In those cases, streaming line by line or chunk by chunk is often the better design.

using StreamReader reader = new StreamReader("bigfile.txt");
string line;
while ((line = reader.ReadLine()) != null)
{
    Console.WriteLine(line);
}

This approach is important in log processing, imports, backups, and report generation where files can become very large.

Encoding in File Handling

Text files depend on character encoding. If the wrong encoding is used, characters may appear corrupted. .NET APIs often default sensibly, but some workflows need an explicit encoding such as UTF-8.

using System.Text;

File.WriteAllText("notes.txt", "Hello", Encoding.UTF8);

This matters especially when exchanging files between systems, regions, or tools that have different encoding expectations.

Working with Temporary Files

Some workflows need temporary files for staging, export generation, intermediate transforms, or testing. The .NET APIs can help generate temporary file paths safely.

string tempFile = Path.GetTempFileName();

Temporary-file handling should still include cleanup, especially in long-running services or bulk-processing tools.

File Sharing and Locks

Sometimes another process may already be using the file you want to open. In lower-level stream APIs, file share settings can control how other processes may access the same file while it is open.

using FileStream stream = new FileStream(
    "shared.txt",
    FileMode.OpenOrCreate,
    FileAccess.ReadWrite,
    FileShare.Read);

Understanding sharing rules matters in multi-process environments, background jobs, and systems that watch or rotate files.

Directory Traversal in Real Systems

Directory traversal is common when building import tools, batch processors, file watchers, media libraries, or backup utilities. Methods such as GetFiles() and GetDirectories() make it possible to scan folder trees, but large directory structures still require thoughtful performance and error handling.

This is another area where file handling becomes more than simple syntax. It becomes part of application design and operational reliability.


Continue learning C# in order
Follow the topic sequence with the previous and next lesson.