Thanks to visit codestin.com
Credit goes to github.com

Skip to content

stevehansen/csv

Repository files navigation

csv

NuGet Version NuGet Downloads Build status codecov

Really simple csv library

This library targets .NET Standard 2.0, .NET 8.0, and .NET 9.0, with enhanced Span/Memory APIs available for .NET 8.0+.

Install

To install csv, use the following command in the Package Manager Console

PM> Install-Package Csv

Changelog

For a detailed list of changes and version history, see CHANGELOG.md.

Basic Usage

More examples can be found in the tests.

Reading a CSV file

// NOTE: Library assumes that the csv data will have a header row by default, see CsvOptions.HeaderMode
/*
# comments are ignored
Column name,Second column,Third column
First cell,second cell,
Second row,second cell,third cell
*/ 
var csv = File.ReadAllText("sample.csv");
foreach (var line in CsvReader.ReadFromText(csv))
{
    // Header is handled, each line will contain the actual row data
    var firstCell = line[0];
    var byName = line["Column name"];
}

CsvReader also supports reading from a TextReader (CsvReader.Read(TextReader, CsvOptions)) or a Stream (CsvReader.ReadFromStream(Stream, CsvOptions))

For .NET 8.0+ the library exposes:

  • CsvReader.ReadAsync and CsvReader.ReadFromStreamAsync which return IAsyncEnumerable<ICsvLine>
  • CsvReader.ReadFromMemory to read from a ReadOnlyMemory<char> without allocating intermediate strings
  • CsvReader.ReadAsSpan, CsvReader.ReadFromStreamAsSpan, and CsvReader.ReadFromTextAsSpan which return IEnumerable<ICsvLineSpan> for zero-allocation Span/Memory access to CSV data
  • CsvReader.ReadFromMemoryOptimized with CsvMemoryOptions for high-performance scenarios using ArrayPool-based buffering

High-performance reading with Span/Memory (.NET 8.0+)

var csv = File.ReadAllText("sample.csv");
foreach (var line in CsvReader.ReadFromTextAsSpan(csv))
{
    // Access data as ReadOnlySpan<char> for zero allocations
    ReadOnlySpan<char> firstCell = line.GetSpan(0);
    ReadOnlySpan<char> byName = line.GetSpan("Column name");

    // Or as ReadOnlyMemory<char> if you need to store references
    ReadOnlyMemory<char> cellMemory = line.GetMemory(0);
}

CsvOptions can be used to configure the csv parsing:

var options = new CsvOptions // Defaults
{
    RowsToSkip = 0, // Allows skipping of initial rows without csv data
    SkipRow = (row, idx) => string.IsNullOrEmpty(row) || row[0] == '#',
    Separator = '\0', // Autodetects based on first row
    TrimData = false, // Can be used to trim each cell
    Comparer = null, // Can be used for case-insensitive comparison for names
    HeaderMode = HeaderMode.HeaderPresent, // Assumes first row is a header row
    AutoRenameHeaders = true, // Automatically renames duplicate headers (e.g., "A", "A2", "A3") and converts empty headers to "Empty", "Empty2", etc. Set to false to throw on duplicates.
    ValidateColumnCount = false, // Checks each row immediately for column count
    ReturnEmptyForMissingColumn = false, // Allows for accessing invalid column names
    Aliases = null, // A collection of alternative column names
    AllowNewLineInEnclosedFieldValues = false, // Respects new line (either \r\n or \n) characters inside field values enclosed in double quotes.
    AllowBackSlashToEscapeQuote = false, // Allows the sequence "\"" to be a valid quoted value (in addition to the standard """")
    AllowSingleQuoteToEncloseFieldValues = false, // Allows the single-quote character to be used to enclose field values
    NewLine = Environment.NewLine // The new line string to use when multiline field values are read (Requires "AllowNewLineInEnclosedFieldValues" to be set to "true" for this to have any effect.)
};

Writing a CSV file

With headers

var columnNames = new [] { "Id", "Name" };
var rows = new []
{
    new [] { "0", "John Doe" },
    new [] { "1", "Jane Doe" }
};
var csv = CsvWriter.WriteToText(columnNames, rows, ',');
File.WriteAllText("people.csv", csv);
/*
Writes the following to the file:

Id,Name
0,John Doe
1,Jane Doe
*/

Without headers

var rows = new []
{
    new [] { "0", "John Doe" },
    new [] { "1", "Jane Doe" }
};
// Convenience overload - no need to pass headers or skipHeaderRow
var csv = CsvWriter.WriteToText(rows);
File.WriteAllText("people.csv", csv);
/*
Writes the following to the file (no header row):

0,John Doe
1,Jane Doe
*/

Skipping headers

var columnNames = new [] { "Id", "Name" };
var rows = new []
{
    new [] { "0", "John Doe" },
    new [] { "1", "Jane Doe" }
};
// Pass null for headers and skipHeaderRow: true
// Column count is determined from the first data row
var csv = CsvWriter.WriteToText(null, rows, ',', skipHeaderRow: true);

Custom separator

var rows = new [] { new [] { "A", "B" }, new [] { "C", "D" } };
var csv = CsvWriter.WriteToText(rows, ';'); // semicolon separator
// Output: A;B
//         C;D

CsvWriter also includes asynchronous overloads (WriteAsync and WriteToTextAsync) which operate on IAsyncEnumerable<string[]> and support passing a CancellationToken. For .NET 8.0+, memory-efficient overloads using ReadOnlyMemory<char> are available.

Helper extensions

CsvReader provides extension methods to work with the returned IEnumerable<ICsvLine>:

  • GetColumn(int columnNo) / GetColumn<T>(int columnNo, Func<string, T>) – extract a single column from all rows.
  • GetBlock(int row_start = 0, int row_length = -1, int col_start = 0, int col_length = -1) – get a rectangular subset of the data.

Status

NuGet Version NuGet Downloads Build status codecov FOSSA Status

License

FOSSA Status

About

Really simple csv library

Topics

Resources

License

Stars

Watchers

Forks

Contributors 13

Languages