技术频道导航
HTML/CSS
.NET技术
IIS技术
PHP技术
Js/JQuery
Photoshop
Fireworks
服务器技术
操作系统
网站运营

赞助商

分类目录

赞助商

最新文章

搜索

TinyCsvParser - 使用C#解析CSV数据

作者:admin    时间:2023-5-19 23:50:41    浏览:

关于使用C#解析、读写CSV数据,前面我已经介绍过几个方法,可参阅下面文章。

本文中,我将介绍另一个方法,那就是使用 TinyCsvParser , 一个CSV解析器。

TinyCsvParser 介绍

TinyCsvParser 是一个 .NET 库,用于以简单的方式解析 CSV 数据,同时提供非常高性能和非常干净的 API。它是高度可配置的,以提供最大的灵活性。

TinyCsvParser 支持 .NET Core。

我们可以在 github 查看 TinyCsvParser 的最新信息、使用说明及发行版本,并下载它:

https://github.com/bytefish/TinyCsvParser

我们还可以使用 NuGet 包。要安装 TinyCsvParser ,请在程序包管理器控制台中运行以下命令。

PM> Install-Package TinyCsvParser

基本用法

想象一下,我们在 CSV 文件中有一个人的列表,其中包含他们的名字、姓氏和生日。

Philipp;Wagner;1986/05/12
Max;Musterman;2014/01/02

我们系统中相应的域模型可能如下所示。

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDate { get; set; }
}

使用TinyCsvParser时,必须定义 CSV 数据中的列与域模型中的属性之间的映射。

public class CsvPersonMapping : CsvMapping<Person>
{
    public CsvPersonMapping()
        : base()
    {
        MapProperty(0, x => x.FirstName);
        MapProperty(1, x => x.LastName);
        MapProperty(2, x => x.BirthDate);
    }
}

然后我们可以通过CsvParser使用映射来解析。

namespace TinyCsvParser.Test
{
    [TestFixture]
    public class TinyCsvParserTest
    {
        [Test]
        public void TinyCsvTest()
        {
            CsvParserOptions csvParserOptions = new CsvParserOptions(true, new[] { ';' });
            CsvReaderOptions csvReaderOptions = new CsvReaderOptions(new[] { Environment.NewLine });
            CsvPersonMapping csvMapper = new CsvPersonMapping();
            CsvParser<Person> csvParser = new CsvParser<Person>(csvParserOptions, csvMapper);

            var stringBuilder = new StringBuilder()
                .AppendLine("FirstName;LastName;BirthDate")
                .AppendLine("Philipp;Wagner;1986/05/12")
                .AppendLine("Max;Mustermann;2014/01/01");

            var result = csvParser
                .ReadFromString(csvReaderOptions, stringBuilder.ToString())
                .ToList();

            Assert.AreEqual(2, result.Count);

            Assert.IsTrue(result.All(x => x.IsValid));

            // Asserts ...
        }
    }
}

就是这样!示例中的CsvParserOptions设置为跳过标题,使用\n为行分隔符和;为列分隔符。

高级用法

自定义类型转换器

现在想象一下,你的客户突然将一个人的生日更改为一种奇怪的格式,并像这样写日期2004###01###25。我们无法使用默认转换器解析此类日期格式,但在TinyCsvParser中,我们可以轻松定义DateTimeConverter具有自定义日期时间格式。

映射属性时,你可以使用WithCustomConverter方法覆盖默认转换器。我们用给定的格式yyyy###MM###dd实例化DateTimeConverter

private class CsvPersonMappingWithCustomConverter : CsvMapping<Person>
{
    public CsvPersonMappingWithCustomConverter()
    {
        MapProperty(0, x => x.FirstName);
        MapProperty(1, x => x.LastName);
        MapProperty(2, x => x.BirthDate)
            .WithCustomConverter(new DateTimeConverter("yyyy###MM###dd"));
    }
}

然后让我们编写一个单元测试来验证预期的结果。

[Test]
public void WeirdDateTimeTest_CustomConverterBased()
{
    CsvParserOptions csvParserOptions = new CsvParserOptions(true, new[] { ';' });
    CsvReaderOptions csvReaderOptions = new CsvReaderOptions(new[] { Environment.NewLine });
    CsvPersonMappingWithCustomConverter csvMapper = new CsvPersonMappingWithCustomConverter();
    CsvParser<Person> csvParser = new CsvParser<Person>(csvParserOptions, csvMapper);

    var stringBuilder = new StringBuilder()
        .AppendLine("FirstName;LastName;BirthDate")
        .AppendLine("Philipp;Wagner;1986###05###12");

    var result = csvParser
        .ReadFromString(csvReaderOptions, stringBuilder.ToString())
        .ToList();

    Assert.AreEqual("Philipp", result[0].Result.FirstName);
    Assert.AreEqual("Wagner", result[0].Result.LastName);

    Assert.AreEqual(1986, result[0].Result.BirthDate.Year);
    Assert.AreEqual(5, result[0].Result.BirthDate.Month);
    Assert.AreEqual(12, result[0].Result.BirthDate.Day);
}

就是这样!

使用 PLINQ 发挥作用

解析器返回一个ParallelQuery,可用于对数据执行其他处理。我认为 LINQ 是 C# 中最神奇的东西之一!我能够在根本不处理锁或线程的情况下并行化整个解析。

在这个例子中,我们将解析数据并搜索所有 first name 含有Philipp的名字 。看看我们如何根本不需要编写 if 语句?

[Test]
public void ParallelLinqTest()
{
    CsvParserOptions csvParserOptions = new CsvParserOptions(true, new[] { ';' });
    CsvReaderOptions csvReaderOptions = new CsvReaderOptions(new[] { Environment.NewLine });
    CsvPersonMapping csvMapper = new CsvPersonMapping();
    CsvParser<Person> csvParser = new CsvParser<Person>(csvParserOptions, csvMapper);

    var stringBuilder = new StringBuilder()
        .AppendLine("FirstName;LastName;BirthDate")
        .AppendLine("Philipp;Wagner;1986/05/12")
        .AppendLine("Max;Mustermann;2014/01/01");

    var result = csvParser
        .ReadFromString(csvReaderOptions, stringBuilder.ToString())
        .Where(x => x.IsValid)
        .Where(x => x.Result.FirstName == "Philipp")
        .ToList();

    Assert.AreEqual(1, result.Count);

    Assert.AreEqual("Philipp", result[0].Result.FirstName);
    Assert.AreEqual("Wagner", result[0].Result.LastName);

    Assert.AreEqual(1986, result[0].Result.BirthDate.Year);
    Assert.AreEqual(5, result[0].Result.BirthDate.Month);
    Assert.AreEqual(12, result[0].Result.BirthDate.Day);
}

总结

本文介绍了一个解析CSV数据的方法——TinyCsvParser,它在 C# 中构建了一个干净、易于使用且高性能的 CSV 解析库。

有关解析CSV的方法,我曾介绍过其他一些,你可参阅以下文章:

 

标签: TinyCsvParser  CSharp  asp.net  CSV  
x
  • 站长推荐
/* 左侧显示文章内容目录 */