File I/O
Reading and writing files
Introduction
In this lesson, you'll learn about file i/o in C#. Coming from C, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In C, you're familiar with reading and writing files.
C# has its own approach to reading and writing files, which we'll explore step by step.
The C# Way
Let's see how C# handles this concept. Here's a typical example:
using System.IO;
// Write — auto-closes with using
File.WriteAllText("output.txt", "Hello, World!\n");
// Read all at once
string content = File.ReadAllText("input.txt");
string[] lines = File.ReadAllLines("input.txt");
// Read line by line (memory-efficient)
using var reader = new StreamReader("input.txt");
string? line;
while ((line = reader.ReadLine()) != null) {
Console.WriteLine(line);
}
// Write with stream
using var writer = new StreamWriter("output.txt", append: true);
writer.WriteLine("New line");
// Binary
byte[] data = File.ReadAllBytes("data.bin");
File.WriteAllBytes("output.bin", data);Comparing to C
Here's how you might have written similar code in C:
#include <stdio.h>
/* Write */
FILE *f = fopen("output.txt", "w");
if (!f) { return 1; }
fprintf(f, "Hello, World!\n");
fclose(f);
/* Read line by line */
FILE *r = fopen("input.txt", "r");
if (!r) { return 1; }
char line[256];
while (fgets(line, sizeof(line), r)) {
printf("%s", line);
}
fclose(r);
/* Binary */
FILE *b = fopen("data.bin", "wb");
int nums[] = {1, 2, 3};
fwrite(nums, sizeof(int), 3, b);
fclose(b);You may be used to different syntax or behavior.
C# File class provides one-liner static methods; C needs fopen/fclose wrappers
You may be used to different syntax or behavior.
C# 'using' auto-closes streams; C requires explicit fclose
You may be used to different syntax or behavior.
C# StreamReader.ReadLine() returns null at EOF; C's fgets checks return value
You may be used to different syntax or behavior.
No buffer size limits in C# — strings grow automatically
Step-by-Step Breakdown
1. One-liner File Ops
C#'s static File class provides ReadAllText, WriteAllText, etc. for common operations without stream management.
FILE *f = fopen("file.txt", "r");
char buf[4096]; fread(buf, 1, sizeof(buf), f); fclose(f);string content = File.ReadAllText("file.txt");2. using for Streams
For large files or streaming, use StreamReader/StreamWriter inside a 'using' block — it calls Dispose (like fclose) automatically.
using var reader = new StreamReader("big.txt");
while (reader.ReadLine() is string line)
process(line);3. Exception Handling
C# throws exceptions on file errors instead of returning NULL. Wrap file operations in try/catch for robust error handling.
try {
string text = File.ReadAllText("config.txt");
} catch (FileNotFoundException ex) {
Console.WriteLine("File not found: " + ex.FileName);
} catch (IOException ex) {
Console.WriteLine("IO error: " + ex.Message);
}Common Mistakes
When coming from C, developers often make these mistakes:
- C# File class provides one-liner static methods; C needs fopen/fclose wrappers
- C# 'using' auto-closes streams; C requires explicit fclose
- C# StreamReader.ReadLine() returns null at EOF; C's fgets checks return value
Key Takeaways
- File.ReadAllText/WriteAllText for simple one-liners
- using StreamReader/Writer auto-closes on scope exit
- Exceptions instead of NULL returns for error handling
- No buffer size limits in C# string reading