将对象列表转换为csv的最快方法,其中每个对象值都在新行中

我有一个课程如下:

public class Test { public int Id {get;set;} public string Name { get; set; } public string CreatedDate {get;set;} public string DueDate { get; set; } public string ReferenceNo { get; set; } public string Parent { get; set; } } 

我有一个Test对象列表

 Listtestobjs=new List(); 

现在我想以下列格式将其转换为csv:

“1,John Grisham,9/5 / 2014,9 / 5 / 2014,1356,0 \ n2,Stephen King,9/3 / 2014,9 / 9 / 2014,1367,0 \ n3,The Rainmaker,4 / 9 / 2014,18 / 9 / 2014,1″ ;

我搜索了“将列表转换为csv c#”,我得到的解决方案如下:

 string.Join(",", list.Select(n => n.ToString()).ToArray()) 

但是这不会根据需要放置\ n,即每个对象

除了字符串构建之外还有其他最快的方法吗? 请帮忙…

使用servicestack.text

 Install-Package ServiceStack.Text 

然后使用字符串扩展方法ToCsv(T)/FromCsv()

示例: https : //github.com/ServiceStack/ServiceStack.Text

更新: Servicestack.Text现在在v4中也是免费的,以前是商业版。 无需再指定版本! 快乐连载!

更新:使用ServiceStack.Text.Core for .NET Core。

因为在问题中提到了速度,我的兴趣是关于相对表现可能是什么,以及我能以多快的速度获得它。

我知道StringBuilder被排除在外,但它仍然感觉可能是最快的,而StreamWriter当然具有写入MemoryStream或直接写入文件的优势,这使得它具有多种function。

所以我敲了一个快速测试。

我建立了一个与你的相同的五十万个物品清单。

然后我使用CsvSerializer序列化,并使用两个手动滚动的紧密版本,一个使用StreamWriter到MemoryStream,另一个使用StringBuilder。

手动编码被编码以应对引号,但没有更复杂。 这段代码非常紧凑,我可以管理中间字符串,没有连接……但不是生产,当然没有样式或灵活性的分数。

但是在所有三种方法中输出都是相同的。

时间很有趣:

序列化50万个对象,每个方法运行5次,所有时间都到最近的整个mS:

 StringBuilder 703 734 828 671 718 Avge= 730.8 MemoryStream 812 937 874 890 906 Avge= 883.8 CsvSerializer 1,734 1,469 1,719 1,593 1,578 Avge= 1,618.6 

这是一个高端的i7,有足够的RAM。

在其他条件相同的情况下,我总是会使用这个库。

但是,如果2:1的性能差异变得至关重要,或者RAM或其他问题变得夸大了较大数据集的差异,或者数据是以块的forms到达并且要直接发送到磁盘,我可能会受到诱惑…

万一有人感兴趣,代码的核心(对于StringBuilder版本)是

  private void writeProperty(StringBuilder sb, string value, bool first, bool last) { if (! value.Contains('\"')) { if (!first) sb.Append(','); sb.Append(value); if (last) sb.AppendLine(); } else { if (!first) sb.Append(",\""); else sb.Append('\"'); sb.Append(value.Replace("\"", "\"\"")); if (last) sb.AppendLine("\""); else sb.Append('\"'); } } private void writeItem(StringBuilder sb, Test item) { writeProperty(sb, item.Id.ToString(), true, false); writeProperty(sb, item.Name, false, false); writeProperty(sb, item.CreatedDate, false, false); writeProperty(sb, item.DueDate, false, false); writeProperty(sb, item.ReferenceNo, false, false); writeProperty(sb, item.Parent, false, true); } 

您最好的选择是使用现有的库。 它可以节省您自己搞清楚的麻烦,它可能会处理转义特殊字符,添加标题行等。您可以使用ServiceStack中的CSVSerializer 。 但在nuget还有其他几个。 然后创建CSV将像string csv = CsvSerializer.SerializeToCsv(testobjs);一样简单string csv = CsvSerializer.SerializeToCsv(testobjs);

LINQtoCSV是我发现的最快最轻的,可以在GitHub上找到。 允许您通过属性属性指定选项。

使用Cinchoo ETL

 Install-Package ChoETL 

要么

 Install-Package ChoETL.NETStandard 

示例显示了如何使用它

 List list = new List(); list.Add(new Test { Id = 1, Name = "Tom" }); list.Add(new Test { Id = 2, Name = "Mark" }); using (var w = new ChoCSVWriter(Console.Out) .WithFirstLineHeader() ) { w.Write(list); } 

输出CSV:

 Id,Name,CreatedDate,DueDate,ReferenceNo,Parent 1,Tom,,,, 2,Mark,,,, 

有关更多信息,请访问github

https://github.com/Cinchoo/ChoETL