Introduction to File I/O

Vaibhav • September 10, 2025

In every real-world application, data rarely lives only in memory. Whether you're saving user preferences, logging activity, or processing external datasets, you’ll need to read from and write to files. This is where File I/O (Input/Output) comes in. In C#, the .NET framework provides a rich set of APIs to interact with the file system - from simple text files to complex binary formats.

Why File I/O Matters

Programs often need to persist data beyond their runtime. For example:

  • Saving game progress
  • Logging errors or events
  • Reading configuration settings
  • Processing CSV files for analytics

File I/O allows your application to interact with the operating system’s file system, enabling long-term data storage and retrieval.

File I/O is part of the System.IO namespace in .NET. It includes classes like File, Directory, StreamReader, and StreamWriter.

Basic Terminology

Before diving into code, let’s clarify a few terms:

  • File: A container for data stored on disk.
  • Directory: A folder that holds files and other directories.
  • Stream: A sequence of bytes used to read/write data.
  • Path: The location of a file or directory in the file system.

Reading and Writing Files - A First Look

Let’s start with a simple example: writing a string to a file and reading it back.

string path = "example.txt";

// Write text to the file
File.WriteAllText(path, "Hello, File I/O!");

// Read text from the file
string content = File.ReadAllText(path);
Console.WriteLine(content); // Output: Hello, File I/O!

This example uses File.WriteAllText and File.ReadAllText, which are high-level convenience methods. They handle opening, reading/writing, and closing the file automatically.

These methods are great for small files. For large files or more control, you’ll use streams - covered in a later article.

Understanding File Paths

File paths can be absolute or relative:

// Absolute path
string absolutePath = "C:\\Users\\Vaibhav\\Documents\\data.txt";

// Relative path (relative to current working directory)
string relativePath = "data.txt";

Use Path.Combine to safely build paths across platforms:

string folder = "Logs";
string fileName = "log.txt";
string fullPath = Path.Combine(folder, fileName);
Console.WriteLine(fullPath); // Logs/log.txt (on Unix), Logs\log.txt (on Windows)

Checking File and Directory Existence

Before reading or writing, it’s often useful to check if a file or directory exists:

if (File.Exists("example.txt"))
{
    Console.WriteLine("File exists!");
}

if (!Directory.Exists("Logs"))
{
    Directory.CreateDirectory("Logs");
}

These checks help avoid exceptions and allow your program to respond gracefully.

Common File I/O Exceptions

File I/O can fail for many reasons - missing files, permission issues, disk errors. Always handle exceptions:

try
{
    string content = File.ReadAllText("missing.txt");
}
catch (FileNotFoundException)
{
    Console.WriteLine("File not found.");
}
catch (UnauthorizedAccessException)
{
    Console.WriteLine("Access denied.");
}

Always wrap file operations in try-catch blocks. File systems are external resources and can fail unpredictably.

File I/O in Console Applications

Let’s build a small console app that logs user input to a file:

Console.WriteLine("Enter your name:");
string name = Console.ReadLine();

string logPath = "userlog.txt";
File.AppendAllText(logPath, $"User: {name} at {DateTime.Now}\n");

Console.WriteLine("Name logged successfully.");

This uses File.AppendAllText to add new lines without overwriting existing content.

Understanding File Modes

When working with streams, you’ll specify how the file should be opened:

  • FileMode.Create - overwrite or create new
  • FileMode.Append - add to end
  • FileMode.Open - open existing
using FileStream fs = new FileStream("data.txt", FileMode.Create);

We’ll explore streams in depth in the Stream Classes article.

Permissions and Security

File access can be restricted by OS-level permissions. If your app runs in a sandbox (e.g., web or mobile), you may not have full access to the file system.

Always test file I/O on the target deployment environment. What works locally may fail in production due to permission restrictions.

Summary

File I/O is a foundational skill in C#. Whether you're saving logs, reading configuration files, or processing data, understanding how to interact with the file system is essential. In this article, we introduced the System.IO namespace, explored basic read/write operations, discussed file paths and exceptions, and built a simple logging app. In the next article, we’ll dive deeper into the File and Directory Classes - exploring how to manipulate files and folders programmatically.