C# มีหลายวิธีอ่านไฟล์ ขึ้นอยู่กับประเภทไฟล์ (Text/Binary) และขนาดไฟล์
1. อ่าน Text File แบบบรรทัดต่อบรรทัด (StreamReader) - แนะนำสำหรับไฟล์ใหญ่
using System;
using System.IO;
public class Program
{
public static void Main()
{
string path = @"D:\data.txt";
try
{
using (StreamReader sr = new StreamReader(path))
{
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}");
}
}
}
2. อ่าน Text File ทั้งหมดทีเดียว (File.ReadAllText/Lines) - ใส่ใจได้เฉพาะไฟล์เล็ก
// อ่านทั้งไฟล์เป็น String เดียว
string content = File.ReadAllText(path);
// อ่านเป็น Array ของบรรทัด
string[] lines = File.ReadAllLines(path);
// อ่านแบบ Lazy (Streaming) - .NET Core 2.1+
foreach (string line in File.ReadLines(path))
{
Console.WriteLine(line);
}
3. อ่าน Binary File (BinaryReader)
using System.IO;
public class BinaryReadExample
{
public static void Main()
{
string path = "mydata.bin";
// เขียนก่อน (สำหรับทดสอบ)
WriteBinaryFile(path);
// อ่าน
try
{
using (BinaryReader br = new BinaryReader(File.Open(path, FileMode.Open)))
{
int i = br.ReadInt32();
double d = br.ReadDouble();
bool b = br.ReadBoolean();
string s = br.ReadString();
Console.WriteLine($"Int: {i}");
Console.WriteLine($"Double: {d}");
Console.WriteLine($"Bool: {b}");
Console.WriteLine($"String: {s}");
}
}
catch (EndOfStreamException)
{
Console.WriteLine("File truncated or corrupt");
}
}
static void WriteBinaryFile(string path)
{
using (BinaryWriter bw = new BinaryWriter(File.Create(path)))
{
bw.Write(25);
bw.Write(3.14157);
bw.Write(true);
bw.Write("I am happy");
}
}
}
4. อ่าน Binary เป็น Byte Array
// ไฟล์เล็ก
byte[] data = File.ReadAllBytes(path);
// ไฟล์ใหญ่ - Streaming
using (FileStream fs = File.OpenRead(path))
{
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
{
ProcessBuffer(buffer, bytesRead);
}
}
// .NET 5+ - ReadExactly / ReadAtLeast
byte[] buffer = new byte[100];
int read = await fs.ReadExactlyAsync(buffer); // Throw ถ้าอ่านไม่ครบ
5. Encoding ปัญหาภาษาไทย
// ระบุ Encoding ชัดเจน
using (StreamReader sr = new StreamReader(path, Encoding.UTF8))
{
// หรือ TIS-620 สำหรับไฟล์เก่า
// using (StreamReader sr = new StreamReader(path, Encoding.GetEncoding("TIS-620")))
}
// File.ReadAllText กำหนด Encoding
string content = File.ReadAllText(path, Encoding.UTF8);
// Detect Encoding (Heuristic)
Encoding detected = DetectEncoding(path); // ใช้ Library: Ude.NetStandard
ตารางเปรียบเทียบเมธอด
| เมธอด | Memory | Speed | เหมาะสำหรับ |
|---|---|---|---|
| File.ReadAllText | High (All in Memory) | Fast (Small Files) | Config, Small Text Files |
| File.ReadAllLines | High | Fast | Line-by-line Processing |
| File.ReadLines | Low (Streaming) | Good | Large Files, LINQ |
| StreamReader | Low (Streaming) | Good | Large Files, Custom Parsing |
| BinaryReader | Low | Fast | Structured Binary Data |
| FileStream + Buffer | Low (Controlled) | Fastest | High Performance, Custom Format |
Error Handling Best Practices
public static async Task SafeReadAllTextAsync(string path)
{
try
{
return await File.ReadAllTextAsync(path);
}
catch (FileNotFoundException)
{
throw new FileNotFoundException($"Config file not found: {path}");
}
catch (UnauthorizedAccessException)
{
throw new UnauthorizedAccessException($"No permission to read: {path}");
}
catch (IOException ex) when (ex.HResult == -2147024864) // ERROR_FILE_IN_USE
{
throw new IOException($"File is locked: {path}", ex);
}
}