處理數百 MB 的文字檔,若逐行 ReadLine() 並用 += 串接字串,會因字串不可變特性導致大量記憶體配置與 GC 壓力,效能極差(1 MB 耗時 7 分鐘)。核心優化點有二:使用 StringBuilder 累積輸出、改用 FileStream/BufferedStream 批次讀取 或 Parallel 處理。
string s = ""; s += line; 每次建立新字串物件,複製舊內容,O(N²) 時間複雜度。StreamReader.ReadLine() 內部逐字元尋找換行符,對超大檔案效率低。using System.IO;
using System.Text;
public void ProcessLargeFile(string inputPath, string outputPath) {
const int BufferSize = 1024 * 1024; // 1MB 緩衝
var sb = new StringBuilder(1024 * 1024); // 預分配容量
using (var fs = new FileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, BufferSize))
using (var sr = new StreamReader(fs, Encoding.UTF8, true, BufferSize))
using (var sw = new StreamWriter(outputPath, false, Encoding.UTF8, BufferSize)) {
string line;
while ((line = sr.ReadLine()) != null) {
// 解析轉換邏輯
var parts = line.Split(',', ' ');
if (parts.Length >= 4) {
// 範例轉換:GOTO / 8.39900, -4.61009, 115.00000
// → LIN {E6POS: X 8.39900, Y -8.37946, 115.00000, A 0.000, B 0.000, C 0.000, E1 0.000} C_VEL
string x = parts[1].Trim();
string y = parts[2].Trim();
string z = parts[3].Trim();
sb.Clear();
sb.Append("LIN {E6POS: X ").Append(x)
.Append(", Y ").Append(y)
.Append(", ").Append(z)
.Append(", A 0.000, B 0.000, C 0.000, E1 0.000} C_VEL");
sw.WriteLine(sb.ToString());
}
}
}
}
若轉換邏輯為 CPU 密集型(如複雜數學運算),可用 Parallel.ForEach 或 PLINQ 分塊處理,但需注意輸出順序與寫入同步(建議各執行緒寫暫存檔,最後合併)。
sb.Clear() 重複利用緩衝區。FileStream/StreamReader/StreamWriter 傳入 1MB+ 緩衝,減少系統呼叫。Substring/IndexOf 手工解析更快。File.OpenRead().ReadAsync() 配合 PipeReader 高效讀取。掌握大檔案流式處理與 StringBuilder 模式,是 C# 高效能資料處理的基本功。