Работа с CSV в C# (.NET): Полное руководство
CSV (Comma-Separated Values) — один из самых распространённых форматов для обмена табличными данными. В экосистеме C# (.NET) существует несколько подходов к работе с CSV-файлами: от ручного парсинга до использования мощных сторонних библиотек. В этой статье мы разберём все основные способы чтения, записи и обработки CSV-данных в .NET.
1. Ручной парсинг CSV с помощью StreamReader
Самый простой способ — использовать стандартные классы StreamReader и String.Split. Однако этот метод не учитывает сложные случаи (кавычки, запятые внутри данных, переносы строк).
using System;
using System.IO;
using System.Linq;
public class CsvSimpleReader
{
public void ReadCsv(string filePath)
{
using (var reader = new StreamReader(filePath))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
Console.WriteLine(string.Join(" | ", values));
}
}
}
}
Недостатки: не обрабатывает экранированные запятые и кавычки. Для реальных проектов используйте более надёжные методы.
2. Использование Microsoft.VisualBasic.FileIO.TextFieldParser (для .NET Framework)
В .NET Framework есть встроенный парсер CSV — TextFieldParser. Он корректно обрабатывает кавычки и разделители.
using Microsoft.VisualBasic.FileIO;
using System;
using System.IO;
public class CsvTextFieldParser
{
public void ParseCsv(string filePath)
{
using (var parser = new TextFieldParser(filePath))
{
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
while (!parser.EndOfData)
{
string[] fields = parser.ReadFields();
Console.WriteLine(string.Join(" | ", fields));
}
}
}
}
Важно: В .NET Core / .NET 5+ этот класс доступен через пакет Microsoft.VisualBasic (NuGet).
3. Библиотека CsvHelper (рекомендуемый способ)
CsvHelper — самая популярная библиотека для работы с CSV в .NET. Она поддерживает маппинг на классы, LINQ-запросы, конфигурацию разделителей и кодировок.
Установка через NuGet:
Install-Package CsvHelper
3.1 Чтение CSV в список объектов
using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;
using System.IO;
using System.Linq;
using System.Collections.Generic;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
public void ReadCsvWithCsvHelper(string filePath)
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
HasHeaderRecord = true,
Delimiter = ",",
MissingFieldFound = null
};
using (var reader = new StreamReader(filePath))
using (var csv = new CsvReader(reader, config))
{
var records = csv.GetRecords<Person>().ToList();
foreach (var person in records)
{
Console.WriteLine($"{person.Name}, {person.Age}, {person.Email}");
}
}
}
3.2 Запись CSV из коллекции объектов
public void WriteCsvWithCsvHelper(string filePath, List<Person> people)
{
using (var writer = new StreamWriter(filePath))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(people);
}
}
3.3 Ручное управление полями (без маппинга)
public void ManualCsvWrite(string filePath)
{
using (var writer = new StreamWriter(filePath))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteField("Name");
csv.WriteField("Age");
csv.NextRecord();
csv.WriteField("Alice");
csv.WriteField(30);
csv.NextRecord();
}
}
4. Обработка CSV с помощью LINQ и маппинга
CsvHelper отлично интегрируется с LINQ. Вы можете фильтровать, сортировать и группировать данные прямо во время чтения:
var adults = csv.GetRecords<Person>()
.Where(p => p.Age >= 18)
.OrderBy(p => p.Name)
.ToList();
5. Работа с большими файлами и потоковая обработка
Для файлов размером более 100 МБ используйте потоковое чтение без загрузки всего файла в память:
using (var reader = new StreamReader("large.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords<Person>();
foreach (var person in records) // данные читаются построчно
{
ProcessPerson(person);
}
}