C Sharp CSV 文件处理
外观
C# CSV文件处理[编辑 | 编辑源代码]
CSV(Comma-Separated Values)是一种简单的文件格式,用于存储表格数据(如电子表格或数据库)。在C#中处理CSV文件是常见的任务,特别是在数据导入/导出、报表生成等场景中。
CSV格式简介[编辑 | 编辑源代码]
CSV文件由以下特点组成:
- 每行代表一条记录
- 记录由分隔符(通常是逗号)分隔的字段组成
- 第一行通常是标题行(可选)
- 字段值可以包含在引号中(特别是当值本身包含分隔符时)
示例CSV文件内容:
Name,Age,Email
"John Doe",30,john@example.com
"Jane Smith",25,jane@example.com
C#中的基本CSV处理[编辑 | 编辑源代码]
使用字符串分割[编辑 | 编辑源代码]
对于简单的CSV文件,可以使用字符串分割方法:
using System;
using System.IO;
class CSVReader
{
static void Main()
{
string filePath = "data.csv";
try
{
string[] lines = File.ReadAllLines(filePath);
// 假设第一行是标题
string[] headers = lines[0].Split(',');
for (int i = 1; i < lines.Length; i++)
{
string[] fields = lines[i].Split(',');
Console.WriteLine($"Record {i}:");
for (int j = 0; j < fields.Length; j++)
{
Console.WriteLine($" {headers[j]}: {fields[j]}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error reading CSV: {ex.Message}");
}
}
}
输出示例:
Record 1:
Name: "John Doe"
Age: 30
Email: john@example.com
Record 2:
Name: "Jane Smith"
Age: 25
Email: jane@example.com
处理带引号的字段[编辑 | 编辑源代码]
当字段包含分隔符时,简单的Split方法会失效。可以使用正则表达式或更复杂的解析逻辑:
using System.Text.RegularExpressions;
// 改进的分割方法,处理带引号的字段
string[] SplitCSVLine(string line)
{
var pattern = ",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))";
return Regex.Split(line, pattern);
}
使用专用库处理CSV[编辑 | 编辑源代码]
对于更复杂的CSV处理,推荐使用专用库如CsvHelper。
安装CsvHelper[编辑 | 编辑源代码]
通过NuGet包管理器安装:
Install-Package CsvHelper
基本用法示例[编辑 | 编辑源代码]
using CsvHelper;
using System.Globalization;
using System.IO;
using System.Linq;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
class Program
{
static void Main()
{
// 读取CSV
using (var reader = new StreamReader("data.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords<Person>().ToList();
foreach (var person in records)
{
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}, Email: {person.Email}");
}
}
// 写入CSV
var people = new List<Person>
{
new Person { Name = "John Doe", Age = 30, Email = "john@example.com" },
new Person { Name = "Jane Smith", Age = 25, Email = "jane@example.com" }
};
using (var writer = new StreamWriter("output.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(people);
}
}
}
高级主题[编辑 | 编辑源代码]
处理大型CSV文件[编辑 | 编辑源代码]
对于大型CSV文件,应使用流式处理而非一次性加载全部内容:
using (var reader = new StreamReader("largefile.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
csv.Read();
csv.ReadHeader();
while (csv.Read())
{
var record = csv.GetRecord<Person>();
// 处理每条记录
}
}
自定义映射[编辑 | 编辑源代码]
当CSV列名与类属性名不匹配时,可以使用自定义映射:
public sealed class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Map(m => m.Name).Name("FullName");
Map(m => m.Age).Name("Years");
Map(m => m.Email).Name("EmailAddress");
}
}
// 使用前注册映射
csv.Context.RegisterClassMap<PersonMap>();
实际应用案例[编辑 | 编辑源代码]
案例1:导入用户数据[编辑 | 编辑源代码]
假设需要从CSV导入用户数据到数据库:
public void ImportUsersFromCSV(string filePath)
{
using (var reader = new StreamReader(filePath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var users = csv.GetRecords<User>().ToList();
using (var dbContext = new AppDbContext())
{
dbContext.Users.AddRange(users);
dbContext.SaveChanges();
}
}
}
案例2:生成报表[编辑 | 编辑源代码]
从数据库查询数据并导出为CSV报表:
public void ExportReportToCSV(string filePath)
{
using (var dbContext = new AppDbContext())
{
var reportData = dbContext.Sales
.Where(s => s.Date.Year == DateTime.Now.Year)
.OrderBy(s => s.Date)
.ToList();
using (var writer = new StreamWriter(filePath))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(reportData);
}
}
}
性能考虑[编辑 | 编辑源代码]
处理CSV文件时应注意以下性能因素:
- 对于大文件,使用流式处理而非一次性加载
- 考虑使用并行处理(当记录间无依赖时)
- 适当使用缓冲(BufferSize)
- 避免不必要的类型转换
常见问题与解决方案[编辑 | 编辑源代码]
问题 | 解决方案 |
---|---|
字段包含分隔符 | 确保字段用引号括起来,使用正确的解析方法 |
多行字段 | 使用支持多行字段的解析库 |
编码问题 | 明确指定文件编码(如UTF-8) |
性能问题 | 使用流式处理,考虑内存映射文件 |
日期格式不一致 | 在读取时指定文化信息或自定义转换器 |
总结[编辑 | 编辑源代码]
C#提供了多种处理CSV文件的方法,从简单的字符串分割到使用功能丰富的第三方库。选择哪种方法取决于具体需求:
- 对于简单、格式规范的CSV,内置方法可能足够
- 对于复杂或生产环境的需求,推荐使用CsvHelper等专业库
- 处理大型文件时,务必考虑内存使用和性能优化
掌握CSV文件处理是C#开发中的实用技能,适用于各种数据交换和报表生成场景。