File I/O
## Learning Objectives
- Read and write text files
- Use StreamReader and StreamWriter
- Work with file paths
- Handle file operations safely
## File Class (Static Methods)
### Simple Operations
```csharp
using System.IO;
// Read all text
string content = File.ReadAllText("file.txt");
// Write all text
File.WriteAllText("output.txt", "Hello, World!");
// Read all lines
string[] lines = File.ReadAllLines("file.txt");
// Write all lines
File.WriteAllLines("output.txt", new[] { "Line 1", "Line 2" });
```
### File Methods
```csharp
File.Exists("file.txt"); // Check if exists
File.Copy("source.txt", "dest.txt"); // Copy
File.Copy("source.txt", "dest.txt", true); // Overwrite
File.Move("source.txt", "dest.txt"); // Move/Rename
File.Delete("file.txt"); // Delete
File.GetCreationTime("file.txt"); // Date created
File.GetLastWriteTime("file.txt"); // Date modified
File.GetLastAccessTime("file.txt"); // Date accessed
```
## StreamReader
### Reading Text
```csharp
using System.IO;
// Read entire file
using (StreamReader reader = new StreamReader("file.txt"))
{
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
// Read line by line
using (StreamReader reader = new StreamReader("file.txt"))
{
string? line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
// Read single character
using (StreamReader reader = new StreamReader("file.txt"))
{
int c = reader.Read(); // Returns int, -1 at EOF
}
```
### StreamReader Methods
```csharp
reader.Peek(); // Look at next char without consuming
reader.Read(); // Read single char
reader.ReadLine(); // Read until newline
reader.ReadToEnd(); // Read rest of file
reader.EndOfStream; // true if at end
```
## StreamWriter
### Writing Text
```csharp
using System.IO;
// Create/overwrite file
using (StreamWriter writer = new StreamWriter("output.txt"))
{
writer.Write("Hello");
writer.WriteLine(" World");
writer.WriteLine("Line 3");
}
// Append to file
using (StreamWriter writer = new StreamWriter("output.txt", append: true))
{
writer.WriteLine("Appended line");
}
```
### StreamWriter Methods
```csharp
writer.Write("text"); // Write without newline
writer.WriteLine("text"); // Write with newline
writer.Flush(); // Force write to disk
writer.AutoFlush = true; // Auto flush after each write
```
## Using Statement
### Automatic Disposal
```csharp
// Correct - using ensures disposal
using (StreamReader reader = new StreamReader("file.txt"))
{
string content = reader.ReadToEnd();
}
// reader is disposed here
// Wrong - file may stay locked
StreamReader reader2 = new StreamReader("file.txt");
string content = reader2.ReadToEnd();
reader2.Dispose(); // Must manually dispose
```
### Nested Using
```csharp
using (StreamReader reader = new StreamReader("input.txt"))
using (StreamWriter writer = new StreamWriter("output.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
writer.WriteLine(line.ToUpper());
}
}
```
## File Paths
### Path Class
```csharp
using System.IO;
string path = @"C:\Users\John\Documents\file.txt";
Path.GetFileName(path); // "file.txt"
Path.GetFileNameWithoutExtension(path); // "file"
Path.GetExtension(path); // ".txt"
Path.GetDirectoryName(path); // "C:\Users\John\Documents"
Path.GetFullPath(path); // Full path
Path.Combine("folder", "file.txt"); // "folder\file.txt"
```
### Path Methods
```csharp
Path.ChangeExtension(path, ".md"); // Change extension
Path.HasExtension(path); // true
Path.IsPathRooted(path); // true if absolute
Path.TrimEndingExtension(path); // Without extension
```
## Directory Operations
### Directory Class
```csharp
using System.IO;
// Create directory
Directory.CreateDirectory("newfolder");
// Check exists
Directory.Exists("folder"); // true/false
// Get files
string[] files = Directory.GetFiles("folder");
string[] txtFiles = Directory.GetFiles("folder", "*.txt");
// Get directories
string[] dirs = Directory.GetDirectories("folder");
// Delete (must be empty)
Directory.Delete("folder");
Directory.Delete("folder", recursive: true); // With contents
```
### DirectoryInfo
```csharp
DirectoryInfo dir = new DirectoryInfo(".");
Console.WriteLine(dir.Name); // Current folder name
Console.WriteLine(dir.FullName); // Full path
Console.WriteLine(dir.Parent); // Parent directory
Console.WriteLine(dir.Root); // Root directory
foreach (FileInfo file in dir.GetFiles())
{
Console.WriteLine($"{file.Name} ({file.Length} bytes)");
}
```
## FileInfo
### Detailed File Information
```csharp
using System.IO;
FileInfo file = new FileInfo("file.txt");
Console.WriteLine(file.Exists); // true/false
Console.WriteLine(file.Name); // "file.txt"
Console.WriteLine(file.Extension); // ".txt"
Console.WriteLine(file.Length); // Size in bytes
Console.WriteLine(file.CreationTime); // When created
Console.WriteLine(file.LastWriteTime); // When modified
Console.WriteLine(file.LastAccessTime); // When accessed
Console.WriteLine(file.DirectoryName); // Containing folder
```
## Working with JSON
### System.Text.Json (C# 8+)
```csharp
using System.Text.Json;
// Serialize
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Person person = new Person { Name = "Alice", Age = 30 };
string json = JsonSerializer.Serialize(person);
// Deserialize
Person? p = JsonSerializer.Deserialize(json);
// With options
var options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNameCaseInsensitive = true
};
string prettyJson = JsonSerializer.Serialize(person, options);
```
## Working with CSV
### Manual Parsing
```csharp
string[] lines = File.ReadAllLines("data.csv");
foreach (string line in lines)
{
string[] fields = line.Split(',');
Console.WriteLine($"Name: {fields[0]}, Age: {fields[1]}");
}
```
### Writing CSV
```csharp
using System.Text;
var sb = new StringBuilder();
sb.AppendLine("Name,Age,City");
foreach (Person p in people)
{
sb.AppendLine($"{p.Name},{p.Age},{p.City}");
}
File.WriteAllText("output.csv", sb.ToString());
```
## Exception Handling with Files
### Safe File Operations
```csharp
try
{
string content = File.ReadAllText("file.txt");
}
catch (FileNotFoundException)
{
Console.WriteLine("File not found");
}
catch (IOException ex)
{
Console.WriteLine($"IO Error: {ex.Message}");
}
// Safer approach
if (File.Exists("file.txt"))
{
string content = File.ReadAllText("file.txt");
}
```
## Summary
- File class: static methods for simple operations
- StreamReader/StreamWriter: detailed control
- Always use `using` statement for proper disposal
- Path class: manipulate file paths safely
- Directory class: folder operations
- FileInfo/DirectoryInfo: object-oriented approach
- System.Text.Json for JSON serialization
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →