How to Write to a Text File in C#
Writing to a file in C# is straightforward with the static File class. For simple cases, File.WriteAllText and File.WriteAllLines cover most needs. For streaming large amounts of data or appending incrementally, use StreamWriter.
File.WriteAllText — Write a Single String
Creates the file if it doesn't exist, or overwrites it if it does.
using System.IO;
string path = "notes.txt";
File.WriteAllText(path, "Hello, World!");
// With a specific encoding
using System.Text;
File.WriteAllText(path, "Héllo, Wörld!", Encoding.UTF8);File.WriteAllLines — Write a Collection of Lines
Writes each element of the collection on its own line.
string[] lines = { "Line one", "Line two", "Line three" };
File.WriteAllLines("output.txt", lines);
// Works with any IEnumerable<string>
List<string> names = new() { "Alice", "Bob", "Carol" };
File.WriteAllLines("names.txt", names);File.AppendAllText — Append Without Overwriting
string logPath = "log.txt";
File.AppendAllText(logPath, $"[{DateTime.Now}] Application started{Environment.NewLine}");
File.AppendAllText(logPath, $"[{DateTime.Now}] Processing complete{Environment.NewLine}");File.AppendAllLines — Append Multiple Lines
string[] newEntries = { "Entry 4", "Entry 5" };
File.AppendAllLines("log.txt", newEntries);StreamWriter — Full Control Over Writing
Use StreamWriter when you need to write incrementally, control buffering, or keep the file open across multiple writes.
using StreamWriter writer = new StreamWriter("report.txt");
writer.WriteLine("=== Report ===");
writer.WriteLine($"Generated: {DateTime.Now:yyyy-MM-dd HH:mm}");
writer.WriteLine();
for (int i = 1; i <= 5; i++)
writer.WriteLine($"Item {i}: value {i * 10}");
// writer.Dispose() is called automatically by the using statementAppend to an existing file by passing append: true:
using StreamWriter writer = new StreamWriter("log.txt", append: true);
writer.WriteLine($"[{DateTime.Now:HH:mm:ss}] New log entry");Async Variants — WriteAllTextAsync and WriteAllLinesAsync
For I/O-bound operations in async methods, prefer the async overloads to avoid blocking threads.
using System.IO;
await File.WriteAllTextAsync("async-output.txt", "Written asynchronously.");
string[] lines = { "Alpha", "Beta", "Gamma" };
await File.WriteAllLinesAsync("async-lines.txt", lines);
// StreamWriter also supports async
await using StreamWriter writer = new StreamWriter("async-log.txt");
await writer.WriteLineAsync("Async line written.");Writing JSON or Structured Data
For structured data, serialize first and then write.
using System.Text.Json;
var config = new { Host = "localhost", Port = 5432, Debug = true };
string json = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true });
await File.WriteAllTextAsync("config.json", json);Error Handling
Wrap file operations in try/catch to handle missing directories, permission errors, or disk-full conditions.
string path = @"C:\Logs\app.log";
try
{
// Ensure the directory exists before writing
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
await File.AppendAllTextAsync(path, $"[{DateTime.Now}] Entry written{Environment.NewLine}");
}
catch (UnauthorizedAccessException ex)
{
Console.Error.WriteLine($"Permission denied: {ex.Message}");
}
catch (IOException ex)
{
Console.Error.WriteLine($"I/O error: {ex.Message}");
}Real-World Example: CSV Export
public record Product(string Name, decimal Price, int Stock);
List<Product> products = new()
{
new("Widget", 9.99m, 120),
new("Gadget", 24.95m, 45),
new("Doohickey", 4.50m, 300),
};
var lines = new List<string> { "Name,Price,Stock" };
lines.AddRange(products.Select(p => $"{p.Name},{p.Price:F2},{p.Stock}"));
await File.WriteAllLinesAsync("products.csv", lines);
// products.csv:
// Name,Price,Stock
// Widget,9.99,120
// Gadget,24.95,45
// Doohickey,4.50,300Quick Reference
| Scenario | Method |
|---|---|
| Write a string (overwrite) | File.WriteAllText(path, text) |
| Write multiple lines (overwrite) | File.WriteAllLines(path, lines) |
| Append a string | File.AppendAllText(path, text) |
| Append multiple lines | File.AppendAllLines(path, lines) |
| Incremental / streaming write | new StreamWriter(path) |
| Append with StreamWriter | new StreamWriter(path, append: true) |
| Async write | File.WriteAllTextAsync(path, text) |
| Ensure directory exists | Directory.CreateDirectory(dir) |