是否有一种“正确”的方式来读取 CSV 文件 [重复]
Posted
技术标签:
【中文标题】是否有一种“正确”的方式来读取 CSV 文件 [重复]【英文标题】:Is there a "proper" way to read CSV files [duplicate] 【发布时间】:2010-11-09 08:43:52 【问题描述】:可能重复:CSV File Imports in .Net
在 .net 中,是否有应该用于读取 csv 文件的标准库?网络上的所有示例都使用自己的 csv 阅读器/解析器,或者使用 OleDb。
使用这些解决方案中的任何一个都不是问题,我只是想知道是否有一个普遍接受的库(不是我能找到的),或者任何其他“正确”的方式来做到这一点?
【问题讨论】:
这链接为另一个当前已关闭的问题的副本。我投票支持重新开放。 【参考方案1】:CsvReader 是一个相当不错的...它不是 Microsoft,但它运行良好,并且比某些替代品(旧版 OleDb 等)快得多。
【讨论】:
这是我能找到的最好的库。我不得不修复其中的一些错误,这些错误与对某些东西的更模糊的支持有关,但在标准的东西上很好。 IT 的效率有点低,因为它会重复字符串连接。在大多数情况下,通过一些调整,我将其更改为在主循环中使用 StringBuilder,这会给您带来巨大的速度提升 是的,我现在正在调查它——它似乎可以处理很多边缘情况。好像没有其他类似的了。 我实际上是想看看这些人是否想要我的代码更改,而不是尝试自己维护它......【参考方案2】:许多人自己编写的原因之一是 CSV 并不是那么简单。例如:
-
第一行是否包含字段名称?
你们支持日期吗?如果是这样,它们是否以特定的日-月-年顺序被引用并用# 标记包围?
它是否支持出现在引用文本值中的换行符?或者这是否打破了记录?
如何在带引号的字符串中转义引号?您是双引号,还是使用反斜杠或其他转义字符?
支持哪些字符编码?
它如何处理转义的控制字符? X;或 \uXXXX 或其他方法?
这些是一些人们编写自己的解析器的原因,因为他们被困在阅读使用所有这些不同设置创建的文件。或者他们编写自己的序列化程序,因为目标系统有很多这些特质。
如果您不关心这些问题,只需使用最方便的库即可。但要明白他们就在那里。
【讨论】:
这些听起来都是不自己编写的充分理由,除非您想重复其他人已经犯过的错误(并且可能已修复)。 CSV 阅读器应该提供包含字符串的行列表或相应的可迭代对象;日期/数字/任何内容如何存储在 CSV 字段中是非整体应用程序中不同层的关注点。其他几点都是拥有 CSV 读写包的好理由,而不是自己动手。许多 DIY 努力将***重新发明为一个边数少于 6 且没有轴的多边形 :-) 我同意。这就是为什么我鼓励人们不要自己写,或者如果他们必须去思考这些问题。 @lavinio:你给出了你认为人们写自己的理由的理由。您的回答中没有任何内容(即使在您编辑之后)可以以任何方式被解释为鼓励不这样做。 我认为在您了解哪些进程将共享数据之前,您无法正确地做出决定。理想情况下,您会使用预打包的,但我已经花了足够的时间尝试解决与这种“简单”格式的不兼容性问题。 (我在一家数据集成公司工作。)【参考方案3】:VB 命名空间有一个很棒的TextFieldParser 类。我知道,c# 人不喜欢从那种“基本”语言中引用库,但它非常好。
它位于 Microsoft.VisualBasic.FileIO.TextFieldParser
我曾经使用 OLEDB,创建列定义文件等 - 但发现 TextFieldParser 是解析任何分隔文件的非常简单方便的工具。
【讨论】:
是的,我也喜欢这门课……但我真的很奇怪为什么 MS 把它放在一个 VB 特定的程序集中,这没有任何意义! @Thomas:VB 程序员期望易于使用的字符串解析函数,而 C 风格的程序员期望在字符串方面遭受可怕的痛苦。 我最近才发现了这个类,这正是我想要的。它是内置的,易于使用,并且可以处理带引号的分隔字段。当您不需要复杂的解决方案时,我建议您使用它,尤其是在对第三方库不太开放的环境中工作时。【参考方案4】:试试CsvHelper(我维护的一个库)。也可以通过NuGet 获得。
CsvHelper 允许您将 CSV 文件直接读取到您的自定义类中。
var streamReader = // Create a reader to your CSV file.
var csvReader = new CsvReader( streamReader );
List<MyCustomType> myData = csvReader.GetRecords<MyCustomType>();
CsvReader 将根据标题行自动找出如何匹配属性名称(这是可配置的)。它使用编译的表达式树而不是反射,所以速度非常快。
它还具有很强的可扩展性和可配置性。
【讨论】:
在这方面有任何例子,因为项目网站上的文档是准系统!我想读入整个文件,然后允许用户将标题映射到我定义的属性列表 它有望很快转移到 github 存储库中的 wiki。该网站的创建方式非常痛苦。使用沙堡。如果您有具体问题,请提出新的 SO 问题。 看到这个问题:***.com/questions/5496845/… 现在有一个文档站点。 joshclose.github.io/CsvHelper【参考方案5】:KBCsv 是另一种选择,特别是如果您需要效率和处理大量 CSV 文件的能力。
披露:我写了 KBCsv,因此是“KB”;)
【讨论】:
【参考方案6】:经过一番调查,还有这个:http://www.filehelpers.com/
这似乎是一个围绕读取文件的完整框架,而不仅仅是 csv 文件。
(注:只是看了网站上的东西,还没用过)
【讨论】:
【参考方案7】:我很确定您可以使用一行代码将 CSV 文件读入 DataTable。一旦它在 DataTable 中,您就可以排序、过滤、迭代等。
This question 有一些将 CSV 读入 DataTables 的示例。
【讨论】:
我已经走这条路很多次了。当它工作时,它工作正常 - 但当它不起作用时调试问题是一个巨大的痛苦。 嗯?我在 CSV 文件中遇到的唯一问题是数据本身(多余的逗号、缺少引号等),无论您使用哪种解析方法,这些都是问题。 是的,问题几乎总是出在数据上——但数据在哪里?由于限制和缺乏控制,我们开始在每个地方(数百个)切换到 TextFieldParser 类。 90% 的时间都在工作,但是当它没有工作时,错误中没有提供任何帮助。我们创建了一个类库来解决这个问题 - 首先清理原始数据等......如果你还没有尝试过 TextFieldParser 类,你真的应该 - 我们喜欢它 - 并每月解析数百万行 csv 数据以上是关于是否有一种“正确”的方式来读取 CSV 文件 [重复]的主要内容,如果未能解决你的问题,请参考以下文章