StreamReader และ StreamWriter เป็น Class หลักสำหรับอ่าน/เขียน Text File แบบ Streaming (Memory Efficient)
อ่านไฟล์ Text (StreamReader)
using System;
using System.IO;
public class Program
{
public static void Main()
{
string path = @"D:\new.txt";
try
{
// using = Auto Close/Dispose
using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
{
string line;
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
catch (FileNotFoundException)
{
Console.WriteLine("File not found");
}
catch (IOException ex)
{
Console.WriteLine($"IO Error: {ex.Message}");
}
}
}
เขียนไฟล์ Text (StreamWriter)
using System;
using System.IO;
public class Program
{
public static void Main()
{
string[] names = { "Jack", "Tom", "Alice" };
string path = "students.txt";
// เขียนไฟล์ (Overwrite)
using (StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8))
{
foreach (string name in names)
{
sw.WriteLine(name);
}
}
// อ่านกลับมาแสดง
Console.WriteLine("File Contents:");
using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
{
string line;
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
}
ผลลัพธ์
File Contents:
Jack
Tom
Alice
StreamWriter Options
// Append Mode (true = Append, false = Overwrite)
using (var sw = new StreamWriter(path, append: true, Encoding.UTF8))
{
sw.WriteLine("New Line Appended");
}
// AutoFlush - Flush ทุก Write (ช้ากว่า แต่ปลอดภัย)
using (var sw = new StreamWriter(path) { AutoFlush = true })
{
sw.WriteLine("Immediate");
}
// NewLine Customization
using (var sw = new StreamWriter(path))
{
sw.NewLine = "\n"; // Unix Line Ending
sw.WriteLine("Line 1");
sw.WriteLine("Line 2");
}
Modern APIs (.NET Core / .NET 5+)
// Async
await using (var sw = new StreamWriter(path))
{
await sw.WriteLineAsync("Async Write");
}
await using (var sr = new StreamReader(path))
{
while (await sr.ReadLineAsync() is { } line)
{
Console.WriteLine(line);
}
}
// One-liners (Small Files)
await File.WriteAllTextAsync(path, content);
await File.WriteAllLinesAsync(path, lines);
string content = await File.ReadAllTextAsync(path);
string[] lines = await File.ReadAllLinesAsync(path);
// Streaming Lines (Lazy)
foreach (string line in File.ReadLines(path)) { } // IEnumerable
await foreach (string line in File.ReadLinesAsync(path)) { } // IAsyncEnumerable
Encoding Handling
// UTF-8 (Default, No BOM)
new StreamReader(path, new UTF8Encoding(false))
// UTF-8 with BOM
new StreamReader(path, Encoding.UTF8)
// Detect Encoding from BOM
new StreamReader(path, Encoding.UTF8, detectEncodingFromByteOrderMarks: true)
// Legacy Thai (TIS-620 / Windows-874)
new StreamReader(path, Encoding.GetEncoding("TIS-620"))
Error Handling Best Practices
public static async Task SafeReadAllLinesAsync(string path)
{
try
{
return await File.ReadAllLinesAsync(path);
}
catch (FileNotFoundException)
{
throw new FileNotFoundException($"File not found: {path}");
}
catch (UnauthorizedAccessException)
{
throw new UnauthorizedAccessException($"Access denied: {path}");
}
catch (IOException ex) when (ex.HResult == -2147024864) // ERROR_SHARING_VIOLATION
{
throw new IOException($"File is locked by another process: {path}", ex);
}
}
สรุปเลือกใช้
| Scenario | Recommended API |
|---|---|
| Small Text File, Simple | File.ReadAllText / ReadAllLines |
| Large Text File | File.ReadLines / StreamReader |
| Async Required | StreamReader/Writer Async, File.ReadAllTextAsync |
| Append to Log | StreamWriter(append: true) |
| Custom Encoding | StreamReader/Writer with Encoding |
| Binary Data | FileStream / BinaryReader/Writer |