Zaiets.CsvEngine 1.0.0

dotnet add package Zaiets.CsvEngine --version 1.0.0
                    
NuGet\Install-Package Zaiets.CsvEngine -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Zaiets.CsvEngine" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Zaiets.CsvEngine" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Zaiets.CsvEngine" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Zaiets.CsvEngine --version 1.0.0
                    
#r "nuget: Zaiets.CsvEngine, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Zaiets.CsvEngine@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Zaiets.CsvEngine&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Zaiets.CsvEngine&version=1.0.0
                    
Install as a Cake Tool

Zaiets.CsvEngine

High-performance CSV reader/writer for .NET — streaming, typed mapping, large files, custom delimiters.

NuGet License: MIT .NET


Features

  • RFC 4180 compliant — correct handling of quoted fields, embedded commas, and newlines inside quotes
  • Streaming — reads and writes row-by-row; constant memory for arbitrarily large files
  • Typed mapping — map CSV rows directly to your POCO classes via CsvMapper or the [CsvColumn] attribute
  • Async-first — full IAsyncEnumerable<CsvRow> support with cancellation
  • Custom delimiters — comma, tab, semicolon, pipe, or any character
  • Fluent extensions — string.ParseCsvAs<T>(), IEnumerable<T>.ToCsvString(), and more
  • Zero dependencies — pure .NET, no third-party packages

Installation

dotnet add package Zaiets.CsvEngine

Quick start

Read a file into a list of objects

using Zaiets.CsvEngine;

// products.csv:
// Id,Name,Price,InStock
// 1,Widget,9.99,true
// 2,Gadget,24.50,false

var products = Csv.ReadFile<Product>("products.csv");

foreach (var p in products)
    Console.WriteLine($"{p.Name}: ${p.Price}");

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public decimal Price { get; set; }
    public bool InStock { get; set; }
}

Write objects to a file

var products = new[]
{
    new Product { Id = 1, Name = "Widget", Price = 9.99m, InStock = true },
    new Product { Id = 2, Name = "Gadget", Price = 24.50m, InStock = false },
};

Csv.WriteFile("output.csv", products);

Parse a CSV string

string csv = """
    Name,Score
    Alice,95
    Bob,82
    """;

var records = csv.ParseCsvAs<StudentScore>();
// or without mapping:
var rows = csv.ParseCsvRows();
Console.WriteLine(rows[0]["Name"]); // Alice

Serialize to string

string csv = products.ToCsvString();

Attribute mapping

Use [CsvColumn] to control how properties map to columns:

public class Order
{
    [CsvColumn("order_id")]
    public int Id { get; set; }

    [CsvColumn("customer_name")]
    public string Customer { get; set; } = string.Empty;

    [CsvColumn("order_date", Format = "yyyy-MM-dd")]
    public DateOnly OrderDate { get; set; }

    [CsvColumn("total_usd", DefaultValue = "0")]
    public decimal Total { get; set; }

    [CsvIgnore]
    public string InternalNote { get; set; } = string.Empty;  // never written/read
}

var orders = Csv.ReadFile<Order>("orders.csv");

You can also map by column index instead of name:

public class LogEntry
{
    [CsvColumn(0)] public DateTime Timestamp { get; set; }
    [CsvColumn(1)] public string Level { get; set; } = string.Empty;
    [CsvColumn(2)] public string Message { get; set; } = string.Empty;
}

var opts = new CsvOptions { HasHeader = false };
var entries = Csv.ReadFile<LogEntry>("app.log", opts);

Custom delimiters

// Tab-separated
var opts = CsvOptions.Tab;

// Semicolon (European locale files)
var opts = CsvOptions.Semicolon;

// Any character
var opts = new CsvOptions { Delimiter = '|' };

Streaming large files

CsvReader and CsvMapper are fully lazy. Only one row is in memory at a time:

await using var reader = new CsvReader("huge.csv");

await foreach (var row in reader.ReadAllAsync(cancellationToken))
{
    // process row.Get<int>("Id"), row["Name"], etc.
}

Or with type mapping:

await using var reader = new CsvReader("huge.csv");
await foreach (var item in CsvMapper.MapAsync<Product>(reader.ReadAllAsync()))
{
    await db.InsertAsync(item);
}

Low-level row access

CsvRow supports both index and name-based access with optional type conversion:

using var reader = new CsvReader("data.csv");

foreach (var row in reader.ReadAll())
{
    int id        = row.Get<int>("Id");
    string name   = row["Name"];
    decimal price = row.GetOrDefault<decimal>("Price", 0m);
    bool inStock  = row.Get<bool>(3); // by index
}

Low-level writing

await using var writer = new CsvWriter("report.csv");

await writer.WriteHeaderAsync("Date", "Revenue", "Region");

await writer.WriteValuesAsync(cancellationToken,
    DateOnly.FromDateTime(DateTime.Today), 12_500.75m, "EMEA");

Stream and string extensions

// From a stream
await using var fs = File.OpenRead("data.csv");
var items = await fs.ReadCsvAsAsync<Product>();

// Write to a stream
await using var ms = new MemoryStream();
await products.WriteCsvAsync(ms);

// Save directly
await products.SaveCsvAsync("output.csv");

Options reference

Property Default Description
Delimiter , Field separator character
Quote " Quote character for fields with special chars
Escape " Escape character inside quoted fields (RFC 4180: doubled quote)
HasHeader true Treat the first row as a header
SkipEmptyLines true Skip blank lines
TrimFields false Trim whitespace from each field
AllowComments false Skip lines starting with CommentChar
CommentChar # Comment line prefix
Encoding UTF-8 File encoding
BufferSize 65536 Stream buffer size in bytes
FormatProvider Invariant Culture for number/date parsing
NewLine System Line ending written by CsvWriter

License

MIT — see LICENSE.


Author

Vladyslav Zaiets — CTO & Software Architect
sarmkadan.com · github.com/Sarmkadan

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 127 5/3/2026