Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

A lightweight .NET CSV Parser (RFC 4180-like)

License

NotificationsYou must be signed in to change notification settings

nd1012/CSV-Parser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A lightweight .NET Standard 2.0 CSV table (RFC 4180-like) parser.

How to get it

CSV-Parser is available as(NuGet package "CSV-Parser")[https://www.nuget.org/packages/CSV-Parser/].

Usage

Parse a file example:

CsvTabletable=wan24.Data.CsvParser.ParseFile(@"/path/to/file.csv");foreach(string[]rowintable){Console.WriteLine("Row in CSV table:");for(inti=0;i<table.CountColumns;i++){Console.WriteLine($"\t{table.Header[i]}:{row[i]}");}}

Parse a file asynchronous example:

CsvTabletable=awaitwan24.Data.CsvParser.ParseFileAsync(@"/path/to/file.csv");

These static methods are available:

  • ParseFile andParseFileAsync forparsing a CSV file
  • ParseStream andParseStreamAsync forparsing a CSV stream
  • ParseString forparsing a CSV string
  • CountRowsFromFile andCountRowsFromFileAsync forcounting rows of a CSV file
  • CountRowsFromStream andCountRowsFromStreamAsync forcounting rows of a CSV stream
  • CountRowsFromString forcounting rows of a CSV string
  • ParseHeaderFromFile andParseHeaderFromFileAsync forparsing column headers from a CSV file
  • ParseHeaderFromStream andParseHeaderFromStreamAsync forparsing column headers from a CSV stream
  • ParseHeaderFromString forparsing column headers from a CSV string
  • EnumerateFile forenumerating each row from a CSV file
  • EnumerateStream forenumerating each row from a CSV stream
  • EnumerateString forenumerating each row from a CSV string
  • CreateMap forcreating mapping informations
  • Map formapping a row to an object
  • Unmap formapping an object to a row

You may adjust these details using additional parameters:

  • If the first line contains the column headers (default istrue)
  • The field delimiter character (default is comma (,))
  • The string value delimiter character (default is double quotes ("))
  • String encoding to use (default is the .NET encoding)
  • If the stream should be left open (default isfalse)
  • Buffer size in bytes (number of bytes that need to include all header columns, default is 80K)
  • Chunk size in bytes (for filling the buffer, default is 4K)
  • Desired row offset (zero based index of the first row to include in the result)
  • Maximum number of rows to include in the result (beginning from the row offset)

CSV table result

The resulting CSV table object holds the parsed table data:

  • CountColumns: column count
  • CountRows: row count
  • Header: column headers
  • Rows: row data
  • Objects: objects from rows having their type name in the first field
  • AsDictionaries: rows as dictionaries (having the headers as key)
  • Mapping: row <-> object mapping

The overloadedToString method would create CSV table data from a CSV table. Other methods are:

  • CreateHeaders: create automatic headers (0..n)
  • AddColumn: add/insert a column (optional using a field value factory)
  • RemoveColumn: remove a column
  • MoveColumn: move a column to another position
  • SwapColumn: swap two columns
  • ReorderColumns: apply a new column order
  • AddRow: add a validated row
  • Validate: validate the CSV table
  • Clear: clear row (and header) data
  • AsDictionary: get a row as dictionary
  • Clone: create a copy of the CSV table object
  • AsObject: get a row mapped as/to an object
  • AsObjects: enumerate all rows as objects
  • AddObjects: map objects to a new row
  • CreateMapping: create a mapping from the column headers

Reading/writing CSV data from/to a stream

For memory saving stream operations, you might want to use theCsvStream:

// Readingusing(CsvStreamcsv=newCsvStream(File.OpenRead(@"path\to\data.csv"))){csv.SkipHeader();// Or ReadHeader (optional, if any)foreach(string[]rowincsv.Rows)// Or use ReadObjects{// Enumerate rows or use ReadRow or ReadObject instead...}}// Writingusing(CsvStreamcsv=newCsvStream(File.OpenWrite(@"path\to\data.csv"))){csv.WriteHeader(newstring[]{...});// Optionalcsv.WriteRow(...);// Or use WriteObject(s)}

Find all methods as asynchronous versions, having theAsync postfix.

For working with dictionaries, you can use the propertyAsDictionaries or the methodsReadDictionary andReadDictionaryAsync.

Per default when reading a header/row, the size is limited to 80KB. To adjust this value, you can modify these values at construction time:

  • bufferSize: Read buffer size in bytes (= maximum header/row size (default: 80KB))
  • chunkSize: Chunk size in bytes (how many bytes to read before trying to match a header/row from the buffer (default: 4KB))

Reading/writing objects

In order to be able to read/write objects, you need to define a mapping. This mapping is responsible for telling the CSV-Parser from which property to get a row field value, and to which property to write a field value from a row. The mapping also supports value factories which can convert a value, and value validation.

Dictionary<int,CsvMapping>mapping=CsvParser.CreateMapping(newCsvMapping(){Field=0,PropertyName="AnyProperty",ObjectValueFactory= ...,// Convert from string to property value (optional)RowValueFactory= ...,// Convert from property value to string (optional)PreValidation= ...,// Validate a string value from the CSV dataPostValidation= ...// Validate a converted value before setting it as object property value},...);

Set this mapping to theMapping property of aCsvTable, give it to theCsvStream constructor, or as parameter to one of the object mapping methods, if available.

For value conversion,CsvParser.ObjectValueFactories andCsvParser.RowValueFactories offer default converter functions for these types:

  • bool
  • int
  • float
  • char
  • byte[]

You can extend them with any type.

If you want to use the same mapping for the same type everytime when no other mapping was given, you can add a prepared mapping toCsvParser.TypeMappings.

In an object you may use theCsvMappingAttribute attribute for properties that should be mapped:

[CsvMapping(0)]publicstringPropertyName{get;}

The attribute parameter is the index of the related CSV column. Then, for creating a mapping for your object, useCsvParser.CreateMapping without parameters. The returned mapping will be stored in theCsvParser.TypeMappings.

Actually CSV is used to store a table. Each row has a fixed number of fields, maybe a header row is present. But you can use CSV also for storing mixed data - for example different objects:

// Assumed all used types are working with CsvMappingAttribute,// or mapping are prepared in CsvParser.TypeMappings already// Writing objectsusing(CsvStreamcsv=newCsvStream(FileStream.OpenWrite("objects.csv"))){csv.WriteObjectRows(anyObjectInstance,anotherTypeInstance);}// Reading objectsusing(CsvStreamcsv=newCsvStream(FileStream.OpenRead("objects.csv"))){anyObjectInstance=csv.ReadObjectRow()asAnyType;anotherTypeInstance=csv.ReadObjectRow()asAnotherType;}

NOTE: The field mapping needs to count from field index zero, because the mapper will get the row without the first field that contains the type name! This ensures that you can re-use the mapping everywhere.

Using the streamsObjectRows property you can also enumerate trough objects from a CSV file.

CsvTable implementsAsObject,AddObjects andObjects for this purpose.

Ignore errors in CSV data

Usually each row should have the number of fields that equals the number of columns. To ignore, when a row has a different field count:

CsvParser.IgnoreErrors=true;

This setting will also ignorenull headers/values, and if usingToString when a string delimiter is required to produce valid CSV data.

WARNING: Ignoring errors may cause unknown failures and produce invalid CSV data!

Good to know

Even more lightweight versions of this library are available on request. These can come optional without

  • dictionary methods
  • object mapping
  • stream support (and CSV writing support)

That would reduce the functionality to this minimum, which may be enough for supporting a nice CSV import interface only:

  • CSV parsing
  • CSV header parsing
  • CSV file row counting

The resulting DLL file would be smaller than 30KB, if all extended features are excluded.


[8]ページ先頭

©2009-2025 Movatter.jp