CSV(逗點分隔值)是最通用的表格資料交換格式。本文整理 C# 讀取 CSV 的四種主流做法:StreamReader 逐行解析、TextFieldParser (VB 庫)、OLE DB / Jet/ACE Provider 視為資料表、CsvHelper 專用庫,並比較優缺點與適用場景。
using (var sr = new StreamReader("data.csv", Encoding.UTF8))
{
string line;
while ((line = sr.ReadLine()) != null)
{
string[] fields = line.Split(','); // 簡單分割,不處理引號、逗號在欄位內
// 處理 fields...
}
}
缺點:無法正確處理包含逗號、換行、雙引號的欄位(需自寫狀態機解析)。
// 參考 Microsoft.VisualBasic.dll
using (var parser = new TextFieldParser("data.csv") { Delimiters = new[] { "," }, HasFieldsEnclosedInQuotes = true })
{
while (!parser.EndOfData)
{
string[] fields = parser.ReadFields(); // 正確處理引號、逗號、換行
// 處理 fields...
}
}
優點:.NET Framework 內建、標準合規、零額外套件。缺點:在 VB 命名空間、效能較 CsvHelper 稍慢。
string connStr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Data\;Extended Properties='Text;HDR=YES;FMT=Delimited'";
using (var conn = new OleDbConnection(connStr))
using (var cmd = new OleDbCommand("SELECT * FROM data.csv", conn))
{
conn.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read()) { /* reader[0]... */ }
}
}
缺點:需安裝 ACE Provider、64 位元相容性問題、類型推斷不準、大檔案效能差、不支援 .NET Core/Linux。不建議新專案使用。
using (var reader = new StreamReader("data.csv"))
using (var csv = new CsvHelper.CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords(); // 或強型別 GetRecords()
foreach (var rec in records) { /* rec.FieldName */ }
}
優點:極快、記憶體效率(流式)、完整 RFC 4180、強型別映射、屬性/Index 映射、自訂型別轉換、支援 .NET Standard/.NET Core。首選方案。
| 方法 | 套件 | 標準合規 | 效能 | 強型別 | 跨平台 | 建議場景 |
|---|---|---|---|---|---|---|
| StreamReader+Split | 無 | ❌ | 快 | ❌ | ✅ | 極簡單 CSV、教學、極小檔 |
| TextFieldParser | Microsoft.VisualBasic | ✅ | 中 | ❌ | ✅ | 無法引入第三方套件的專案 |
| OLE DB | ACE Provider | 部分 | 慢 | ❌ | ❌ | 舊系統維護、Excel/Access 互操作 |
| CsvHelper | NuGet | ✅ | 極快 | ✅ | ✅ | 所有新專案首選 |
csv.Read() + csv.GetRecord<T>() 逐筆讀取,避免載入全檔。Ude.NetStandard 或 Encoding.GetEncoding("big5") 指定編碼。CsvWriter 同樣高效、支援強型別。Map(m => m.Prop).Name("CSV Header").TypeConverter<MyConverter>()。選對工具,CSV 處理不再是痛點。新專案請直接 Install-Package CsvHelper,專注於業務邏輯而非解析細節。