CsvHelper说明文档&一个小例子
2017-07-25 08:55
351 查看
启动
要安装CsvHelper,请从包管理器控制台运行以下操作。Install-Package CsvHelper
读取文件
读取所有记录。读取设置尽可能简单。 如果您有一个镜像CSV文件的类结构设置,您可以将整个文件读入可枚举。var csv = new CsvReader( textReader ); var records = csv.GetRecords<MyClass>();
如果要自定义CSV文件映射到自定义类对象的方式,可以使用映射。
返回的IEnumerable 将产生结果。 这意味着在实际访问结果之前不会返回结果。 这是方便的,因为整个文件将不会被加载到内存中,并且当您访问每一行时,该文件将被读取。 如果您在IEnumerable 上执行类似Count()的操作,那么需要读取整个文件,您将无法重新遍历它,而不会重新开始。 如果您需要多次迭代记录(例如使用Count),则可以将所有内容加载到列表和数据的工作中。
var csv = new CsvReader( textReader ); var records = csv.GetRecords<MyClass>().ToList();
手动读取记录
您可以循环行并手动读取它们。var csv = new CsvReader( textReader ); while( csv.Read() ) { var record = csv.GetRecord<MyClass>(); }
读取个别字段
您也可以手动阅读每个字段。var csv = new CsvReader( textReader ); while( csv.Read() ) { var intField = csv.GetField<int>( 0 ); var stringField = csv.GetField<string>( 1 ); var boolField = csv.GetField<bool>( "HeaderName" ); }
TryGetField
如果获取字段不一致,可以使用TryGetField。var csv = new CsvReader( textReader ); while( csv.Read() ) { int intField; if( !csv.TryGetField( 0, out intField ) ) { // Do something when it can't convert. } }
解析
您也可以直接使用解析器,而无需使用阅读器。 解析器将返回读取的每行的字符串数组,当它完成时为空。var parser = new CsvParser( textReader ); while( true ) { var row = parser.Read(); if( row == null ) { break; } }
写文件
写入所有记录
写作设置尽可能简单。 如果您有一个镜像CSV文件的类结构设置,您可以从枚举中写入整个文件。var csv = new CsvWriter( textWriter ); csv.WriteRecords( records );
手动写入记录
您可以循环对象并手动写入。var csv = new CsvWriter( textWriter ); foreach( var item in list ) { csv.WriteRecord( item ); }
写入个别字段
如果您愿意,也可以手动写入每个字段。var csv = new CsvWriter( textWriter ); foreach( var item in list ) { csv.WriteField( "a" ); csv.WriteField( 2 ); csv.WriteField( true ); csv.NextRecord(); }
映射(Mapping)
自动映射(Auto Mapping)
如果不提供映射文件,将使用自动映射。 自动映射将按照它们显示的顺序映射类中的属性。如果属性是一个自定义类,它会按照它们显示的顺序递归地将属性从该类映射。如果自动映射器命中循环引用,那么它将停止参考分支。流畅的类映射(Fluent Class Mapping)
如果您的CSV文件与您的自定义类不完全匹配,则可以使用流畅的类映射来设置类映射到文件的选项。 您需要在配置中注册您的类映射。public sealed class MyClassMap : CsvClassMap<MyClass> { public MyClassMap() { Map( m => m.Id ); Map( m = > m.Name ); } }
索引映射(Reference Map)
索引映射用于将自定义类的属性映射到自己的映射,将这些属性映射到多个CSV列。 您可以根据需要将索引映射嵌套得很深。public sealed class PersonMap : CsvClassMap<Person> { public PersonMap() { Map( m => m.Id ); Map( m => m.Name ); References<AddressMap>( m => m.Address ); } } public sealed class AddressMap : CsvClassMap<Address> { public AddressMap() { Map( m => m.Street ); Map( m => m.City ); Map( m => m.State ); Map( m => m.Zip ); } }
索引(Index)
当通过索引映射时,您指定要用于该属性的CSV列的索引。public sealed class MyClassMap : CsvClassMap<MyClass> { public MyClassMap() { Map( m => m.Id ).Index( 0 ); Map( m => m.Name ).Index( 1 ); } }
名称(Name)
当按名称(Name)映射时,您指定要用于该属性的CSV列的名称。 为了使其工作,CSV文件必须具有标题记录。 您指定的名称必须与标题记录的名称相匹配。public sealed class MyClassMap : CsvClassMap<MyClass> { public MyClassMap() { Map( m => m.Id ).Name( "The Id Column" ); Map( m => m.Name ).Name( "The Name Column" ); } }
名称索引(NameIndex)
有时CSV文件有多个名称相同的列。 发生这种情况时,可以使用NameIndex来指定您所指的列名。 NameIndex不是CSV文件中的列。public sealed class MyClassMap : CsvClassMap<MyClass> { public MyClassMap() { Map( m => m.FirstName ).Name( "Name" ).NameIndex( 0 ); Map( m => m.LastName ).Name( "Name" ).NameIndex( 1 ); } }
忽略(Ignore)
目前没有使用。 映射只会映射您指定的属性。 将来会有一个在类映射中自动映射的选项,明确声明的任何映射将覆盖自动映射的映射。 当这种情况发生时,ignore将忽略自动映射的属性默认(Default)
如果字段为空,Default用于设置要使用的默认值。public sealed class MyClassMap : CsvClassMap<MyClass> { public override void MyClassMap() { Map( m => m.Id ).Index( 0 ).Default( -1 ); Map( m => m.Name ).Index( 1 ).Default( "Unknown" ); } }
类型转换(TypeConverter)
如果CSV字段的值不能自动转换为该属性的类型,则可以指定用于转换该值的自定义CsvHelper.TypeConversion.ITypeConverter。 有关如何创建自定义类型转换器的文档,请参阅类型转换。public sealed class MyClassMap : CsvClassMap<MyClass> { public MyClassMap() { Map( m => m.Id ).Index( 0 ).TypeConverter<MyIdConverter>(); } }
类型转换器选项(TypeConverterOption)
默认内置转换器将处理大多数类型转换的情况,但有时您会想要做一些小的更改,但不希望创建一个全新的类型转换器,只需解析一个int(例如)不同的。 您可以指定一些类型转换器选项来处理这些情况。public sealed class MyClassMap : CsvClassMap<MyClass> { public MyClassMap() { Map( m => m.Description ).Index( 0 ).TypeConverterOption( CultureInfo.InvariantCulture ); Map( m => m.TimeStamp ).Index( 1 ).TypeConverterOption( DateTimeStyles.AdjustToUniversal ); Map( m => m.Cost ).Index( 2 ).TypeConverterOption( NumberStyles.Currency ); Map( m => m.CurrencyFormat ).Index( 3 ).TypeConverterOption( "C" ); Map( m => m.BooleanValue ).Index( 4 ).TypeConverterOption( true, "sure" ).TypeConverterOption( false, "nope" ); } }
转换使用(Convert Using)
当其他所有失败时,您都可以使用ConvertUsing。 ConvertUsing允许您编写内嵌自定义代码将该行转换为单个属性值。public sealed class MyClassMap : CsvClassMap<MyClass> { public MyClassMap() { // Constant value. Map( m => m.Constant ).ConvertUsing( row => 3 ); // Aggregate of two rows. Map( m => m.Aggregate ).ConvertUsing( row => row.Get<int>( 0 ) + row.Get<int>( 1 ) ); // Collection with a single value. Map( m => m.Names ).ConvertUsing( row => new List<string>{ row.Get<string>( "Name" ) } ); // Just about anything. Map( m => m.Anything ).ConvertUsing( row => { // You can do anything you want in a block. // Just make sure to return the same type as the property. } ); } }
运行时映射
映射可以在运行时创建。 事实上,自动映射功能会动态地进行。 您可以查看以下链接的一些灵感:https://github.com/JoshClose/CsvHelper/blob/master/src/CsvHelper/Configuration/CsvClassMap.cs#L91另一个简单的例子如下所示:
var customerMap = new DefaultCsvClassMap(); // mapping holds the Property - csv column mapping foreach( string key in mapping.Keys ) { var columnName = mapping[key].ToString(); if( !String.IsNullOrEmpty( columnName ) ) { var propertyInfo = typeof( Customer ).GetType().GetProperty( key ); var newMap = new CsvPropertyMap( propertyInfo ); newMap.Name( columnName ); customerMap.PropertyMaps.Add( newMap ); } } csv.Configuration.RegisterClassMap(CustomerMap);
配置
允许注释(Allow Comments)
该标志告诉解析器是否启用了注释。// Default value csv.Configuration.AllowComments = false;
自动映射(Auto Map)
这用于从类型自动生成CsvClassMap,而无需流畅的类映射。 这将尝试映射所有属性,包括为非本机类型的属性创建引用映射。 如果自动映射器检测到循环引用,则该路径将不会继续。var generatedMap = csv.Configuration.AutoMap<MyClass>();
缓冲区大小(Buffer Size)
当从TextReader和TextWriter读取或写入数据时使用的内部缓冲区的大小。 取决于您的TextReader或TextWriter来自哪里,您可能希望使此值更大或更小。// Default value csv.Configuration.BufferSize = 2048;
注释(Comment)
用于表示被注释掉的行的值。// Default value csv.Configuration.Comment = '#';
计数字节(Count Bytes)
一个标志,将告诉解析器保留已读取的所有字节的计数。 您需要将Configuration.Encoding设置为CSV文件的相同编码,以使其正常工作。 这也将减慢解析文件的速度.// Default value csv.Configuration.CountBytes = false;
Culture Info
用于读写。在索引配置中,每个属性都可以复写。// Default value csv.Configuration.CultureInfo = CultureInfo.CurrentCulture;
分隔符(Delimiter)
用于分隔CSV行中的字段的值。// Default value csv.Configuration.Delimiter = ",";
检测列计数更改(Detect Column Count Changes)
该标志将检查从行到行的列数的更改。 如果为true并检测到更改,则将抛出CsvBadDataException异常。// Default value csv.Configuration.DetectColumnCountChanges = false;
编码(Encoding)
CSV文件的编码。 这仅在计数字节时使用。 TextReader和TextWriter的底层将使用自己的编码。// Default value csv.Configuration.Encoding = Encoding.UTF8;
有标题记录(Has Header Record)
该标志告诉读写器CSV文件中是否有标题行。 对于通过名称映射属性,必须是正确的(并且必须有一个标题行)。// Default value csv.Configuration.HasHeaderRecord = true;
忽略标题空白(Ignore Header White Space)
当通过名称将列与属性匹配时,此标志会告知读者忽略标题中的空格。// Default value csv.Configuration.IgnoreHeaderWhiteSpace = false;
忽略私有访问(Ignore Private Accessor)
一个标志,告诉读写器在读取和写入时忽略私有访问者。 默认情况下,您无法从私有的getter读取或写入私有设置器。 打开它将允许。 无法读取或写入的属性被忽略。// Default value csv.Configuration.IgnorePrivateAccessor = false;
忽略读取异常(Ignore Reading Exceptions)
一个标志,告诉读者吞咽读取时发生的任何异常并继续。 解析器中发生的异常不会被忽略。 解析器异常意味着文件在某些方面是坏的,解析器不能恢复。// Default value csv.Configuration.IgnoreReadingExceptions = false;
忽略引号(Ignore Quotes)
一个标志,告诉解析器忽略引号作为转义字符,并像任何其他字符一样对待它。// Default value csv.Configuration.IgnoreQuotes = false;
标题大小写敏感(Is Header Case Sensitive)
该标志设置匹配的CSV头名称是否区分大小写。// Default value csv.Configuration.IsHeaderCaseSensitive = true;
映射(Maps)
您可以访问注册的类映射。var myMap = csv.Configuration.Maps[typeof( MyClass )];
属性绑定标志(Property Binding Flags)
PropertyBindingFlags是用于在自定义类中查找属性的标志。// Default value csv.Configuration.PropertyBindingFlags = BindingFlags.Public | BindingFlags.Instance;
引号(Quote)
用于转义包含分隔符,引号或行结束的字段的值。// Default value csv.Configuration.Quote = '"';
引用所有字段(Quote All Fields)
一个告诉写入器所有写的字段是否应该有引号; 不管该字段是否包含任何应该被转义的内容。 QuoteAllFields和QuoteNoFields都不能同时存在。 将一个设置为true将将另一个设置为false。// Default value csv.Configuration.QuoteAllFields = false;
不引用字段(Quote No Fields)
一个告诉写入器所写的所有字段是不应该有引号的; 不管该字段是否包含任何应该被转义的内容。 QuoteAllFields和QuoteNoFields都不能同时存在。 将一个设置为true将将另一个设置为false。// Default value csv.Configuration.QuoteNoFields = false;
读取异常回调(Reading Exception Callback)
如果您有Configuration.IgnoreReaderExceptions,并且您想知道异常已经发生,并且可能会与他们做某事,您可以使用它。csv.Configuration.ReadingExceptionCallback = ( ex, row ) => { // Log the exception and current row information. };
注册类映射(Register Class Map)
当使用流畅的类映射时,需要注册类映射才能使用它们。 您可以注册要使用的多个类映射。csv.Configuration.RegisterClassMap<MyClassMap>(); csv.Configuration.RegisterClassMap<AnotherClassMap>();
跳过空记录(Skip Empty Records)
一个标志,让读入器知道当读入时是否应该跳过记录,如果它是空的。 如果所有字段都为空,则记录被视为空。// Default value csv.Configuration.SkipEmptyRecords = false;
修剪字段(Trim Fields)
该标志告诉读者在阅读时从字段值的开头和结尾修剪空格。// Default value csv.Configuration.TrimFields = false;
修剪头(Trim Headers)
这个标志告诉读入器从名称的开头和结尾处忽略空格,并将这些列与属性进行匹配。// Default value csv.Configuration.TrimHeaders = false;
取消注册类映射(Unregister Class Map)
如果需要,您可以取消注册类映射。// Unregister single map. csv.Configuration.UnregisterClassMap<MyClassMap>(); // Unregister all class maps. csv.Configuration.UnregisterClassMap();
字段丢失抛出异常(Will Throw On Missing Field)
此标志指示如果读取和预期字段丢失时是否应抛出异常。 如果您想知道CSV文件是否有问题,这很有用。// Default value csv.Configuration.WillThrowOnMissingField = true;
一个用CsvHelper读取csv文件的例子
//program.cs //用来读取csv文件 using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using CsvHelper; namespace CSVHelperReadSample { internal class Program { private static void Main(string[] args) { //文件流的操作 using (FileStream fileStream = new FileStream(@"D:\path\test.csv", FileMode.Open, FileAccess.Read)) //以GB2312的编码方式读入 using (var sr = new StreamReader(fileStream, Encoding.GetEncoding("GB2312"))) { using (var reader = new CsvReader(sr)) { //读入到枚举,CSVReader会将整个文件读入到一个enumerable中 IEnumerable<StudentInformationClass> records = reader.GetRecords<StudentInformationClass>(); foreach (StudentInformationClass record in records) { Console.Write("{0} {1} {2} {3} {4} {5}\n", record.NoClass, record.StudentNo, record.NameStudent, record.Sex, record.BirthdayStudent, record.GradeStudent); } //objs = reader.GetRecords<StudentInformationClass>().ToList(); } //var objs = new List<StudentInformationClass>(); //CSVReader will now read the whole file into an enumerable //Console.WriteLine(objs.Count); } } } }
//学生信息类 using System; namespace CSVHelperReadSample { public class StudentInformationClass { private int _classNo;//班级号 private string _studentNo;//学号 private string _nameStudent;//学生姓名 private int _gradeStudent;//成绩 private string _sex;//学生姓名 private string _birthdayStudent;//生日 public int NoClass { set { this._classNo = value; } get { return this._classNo; } } public string StudentNo { set { this._studentNo = value; } get { return this._studentNo; } } public string NameStudent { set { this._nameStudent = value; } get { return this._nameStudent; } } public int GradeStudent { set { this._gradeStudent = value; } get { return this._gradeStudent; } } public string Sex { set { this._sex = value; } get { return this._sex; } } public string BirthdayStudent { set { this._birthdayStudent = value; } get { return _birthdayStudent; } } } }
相关文章推荐
- CUDA by Example 4.2.2 一个有趣的例子 之 #include "gl_helper.h"
- Oracle 远程访问配置 在 Windows Forms 和 WPF 应用中使用 FontAwesome 图标 C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素” C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper Decimal类型截取保留N位小数向上取, Decimal类型截取保留N位小数并且不进行四舍五入操作
- Google Earth & Asp.Net 一步一步从入门到精通(一)一个加载KML文档的例子
- Google Earth & Asp.Net 一步一步从入门到精通(一)一个加载KML文档的例子
- 数据结构和算法到底有什么用?一个例子说明。
- 一个例子搞懂Servlet&JSP
- 以一个最简单的例子把OO的JavaScript说明白
- 17、Drools——KieHelper的用法,通过模板的例子说明
- 学习oracle里面触发器的功能作用,举一个例子来说明:
- 在进行嵌入式开发之前,首先要建立一个交叉编译环境,这是一套编译器、连接器和libc库等组成的开发环境。文章通过一个具体的例子说明了这些嵌入式交叉编译开发工具的制作过程。 随着消费类电子产品的大量开发和应用和Linux操作系统的不断健壮和强大,嵌入式系统越来
- D3的一个平移 缩放例子,说明基本用法
- ASP.NET AJAX 说明文档->客户端引用->全局命名空间->JavaScript 基础类型扩展->Array 类型扩展->contains 函数
- 用一个例子来说明程序开发过程中的粒度和弹性控制
- 一个例子说明数据库union all的作用
- session.flush方法到底干了一些什么事情,举一个具体的例子说明
- 一个简单的例子说明dynamic_cast的作用
- [VBA]用一个简单例子说明如何在Excel中自定义函数
- [Unity&JSON]如何在同一个JSON文档中存入多个不同类型的数据
- 说明JavaScript 函数间按值传参的一个例子
- C++简单例子说明一个问题