無論是儲存設定檔、記錄日誌、匯出報表,檔案讀寫都是應用程式的基本功。.NET 提供以 Stream 為核心的分層架構,本文將從建立、寫入、讀取、二進位操作到檔案資訊查詢,完整示範最常用的 API 用法。
Stream (抽象基類)
├── FileStream // 檔案串流,支援同步/非同步、隨機存取
├── MemoryStream // 記憶體串流
└── NetworkStream // 網路串流
文字層包裝:
├── StreamReader / StreamWriter // 字元編碼轉換,預設 UTF-8
└── BinaryReader / BinaryWriter // 基本型別二進位讀寫
using System;
using System.IO;
using System.Text;
public class FileIoDemo
{
public static void Main()
{
const string fileName = "demo.txt";
// 1. 建立檔案並寫入文字 (StreamWriter)
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
using (var sw = new StreamWriter(fs, Encoding.UTF8))
{
sw.WriteLine("Hello, C# File I/O!");
sw.WriteLine("第二行:支援 Unicode 中文。");
sw.WriteLine($"現在時間:{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
sw.Flush(); // 確保緩衝區寫入底層 Stream
}
// 2. 文字模式讀取 (StreamReader)
Console.WriteLine("=== StreamReader 逐行讀取 ===");
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var sr = new StreamReader(fs, Encoding.UTF8))
{
string line;
while ((line = sr.ReadLine()) != null)
Console.WriteLine(line);
}
// 3. 二進位模式讀取 (BinaryReader)
Console.WriteLine("\n=== BinaryReader 逐位元組讀取 ===");
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var br = new BinaryReader(fs, Encoding.UTF8))
{
int b;
while ((b = br.ReadByte()) != -1)
{
char c = (char)b;
Console.Write(c);
if (c != '\r' && c != '\n') Console.Write("."); // 視覺化分隔
}
Console.WriteLine();
}
// 4. 使用 File 靜態類別查詢中繼資料
Console.WriteLine("\n=== File 中繼資料 ===");
FileInfo fi = new FileInfo(fileName);
Console.WriteLine($"檔名: {fi.Name}");
Console.WriteLine($"完整路徑: {fi.FullName}");
Console.WriteLine($"大小: {fi.Length} bytes");
Console.WriteLine($"建立時間: {fi.CreationTime}");
Console.WriteLine($"最後寫入: {fi.LastWriteTime}");
Console.WriteLine($"屬性: {fi.Attributes}");
}
}
| 值 | 行為 |
|---|---|
CreateNew | 建立新檔,若存在則拋出例外 |
Create | 建立新檔,若存在則覆寫 |
Open | 開啟現有檔,不存在則拋出例外 |
OpenOrCreate | 開啟現有檔,不存在則建立 |
Append | 開啟並定位到末尾(僅配合 Write) |
Truncate | 開啟現有檔並截斷為零長度 |
// FileAccess: Read, Write, ReadWrite
// FileShare: None, Read, Write, ReadWrite, Delete, Inheritable
// 建議:讀取時用 FileShare.Read 允許其他程序同時讀取
new StreamWriter(fs, Encoding.UTF8) // 明確指定 UTF-8 (無 BOM 用 new UTF8Encoding(false))
new StreamReader(fs, Encoding.GetEncoding("big5")) // 繁體中文舊系統相容
await using var fs = new FileStream("async.txt", FileMode.Create, FileAccess.Write);
await fs.WriteAsync(Encoding.UTF8.GetBytes("非同步寫入"));
// 讀取
byte[] buffer = new byte[fs.Length];
await fs.ReadAsync(buffer, 0, buffer.Length);
// 一次性讀取所有文字
string allText = File.ReadAllText("demo.txt", Encoding.UTF8);
string[] lines = File.ReadAllLines("demo.txt");
// 一次性寫入
File.WriteAllText("out.txt", "內容");
File.WriteAllLines("out.txt", new[] { "行1", "行2" });
File.AppendAllText("log.txt", $"{DateTime.Now}: Event\n");
foreach (string line in File.ReadLines("huge.log")) // 延遲執行,不一次載入
{
if (line.Contains("ERROR")) ProcessError(line);
}
using 或 await using 確保 Dispose() 被呼叫,釋放檔案鎖定。Encoding.Default)造成亂碼。Path.Combine,不要手動拼接 \\ 或 /。ReadAllText,改用 File.ReadLines 或 StreamReader 串流處理。FileNotFoundException、UnauthorizedAccessException、IOException(磁碟滿、鎖定)皆需捕捉。.NET 的串流架構清晰分層:FileStream 處理位元組與作業系統溝通,StreamReader/Writer 處理字元編碼,BinaryReader/Writer 處理基本型別序列化。掌握這三層的組合與 using 模式,即能應對 95% 的檔案 I/O 需求。