Skip to content

Repository files navigation

csv

NuGet VersionNuGet DownloadsBuild statuscodecov

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 ignoredColumn name,Second column,Third columnFirst cell,second cell,Second row,second cell,third cell*/varcsv=File.ReadAllText("sample.csv");foreach(varlineinCsvReader.ReadFromText(csv)){// Header is handled, each line will contain the actual row datavarfirstCell=line[0];varbyName=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+)

varcsv=File.ReadAllText("sample.csv");foreach(varlineinCsvReader.ReadFromTextAsSpan(csv)){// Access data as ReadOnlySpan<char> for zero allocationsReadOnlySpan<char>firstCell=line.GetSpan(0);ReadOnlySpan<char>byName=line.GetSpan("Column name");// Or as ReadOnlyMemory<char> if you need to store referencesReadOnlyMemory<char>cellMemory=line.GetMemory(0);}

CsvOptions can be used to configure the csv parsing:

varoptions=newCsvOptions// Defaults{RowsToSkip=0,// Allows skipping of initial rows without csv dataSkipRow=(row,idx)=>string.IsNullOrEmpty(row)||row[0]=='#',Separator='\0',// Autodetects based on first rowTrimData=false,// Can be used to trim each cellComparer=null,// Can be used for case-insensitive comparison for namesHeaderMode=HeaderMode.HeaderPresent,// Assumes first row is a header rowAutoRenameHeaders=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 countReturnEmptyForMissingColumn=false,// Allows for accessing invalid column namesAliases=null,// A collection of alternative column namesAllowNewLineInEnclosedFieldValues=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 valuesNewLine=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

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

Without headers

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

Skipping headers

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

Custom separator

varrows=new[]{new[]{"A","B"},new[]{"C","D"}};varcsv=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 VersionNuGet DownloadsBuild statuscodecovFOSSA Status

License

FOSSA Status

About

Really simple csv library

Topics

Resources

Stars

208 stars

Watchers

6 watching

Forks

Used by

Contributors

Languages