CSV(Comma Separated Values,逗号分隔值)文件是一种常见的数据交换格式,尽管大多数CSV文件遵循相对标准的格式,但存在许多变体。常见的变体包括制表符分隔值文件、包含标题行的文件、引用规则的变化以及支持注释字符/行的文件。本文介绍的类简化了多种不同格式的CSV文件的读写操作。
在本文中,CSV指的是字符分隔值(Character Separated Value),其中逗号分隔值是其子类别。演示项目允许显示和操作一些常见的CSV变体,但并未展示包含的类的全部功能。尽管XML文件在当今的常见用法中经常取代CSV文件,但CSV仍然是一个紧凑且简单的替代文件格式。许多不同的应用程序,包括Excel,都能够读写这些文件。
在学习代码时,用户应该关注CsvFormBase
、CsvFormReader
和CsvFormWriter
类,它们提供了代码的一些简单用例。用户界面代码很长,与本文没有直接关系。然而,它确实展示了一些相关主题,如DataGridView
控件和BackgroundWorker
组件。
此外,MainForm
类中的mainBackgroundWorker_DoWork
、mainBackgroundWorker_ProgressChanged
和mainBackgroundWorker_RunWorkerCompleted
方法可能对那些需要在读取或写入CSV文件时报告进度的开发者特别感兴趣。
库中的主要类是CsvReader
和CsvWriter
。由于代码的灵活性,它们支持大量的方法。代码本身是完全注释的,对于这些方法来说,代码本身是最好的信息来源。本文只会描述一些更常见的用例。
最简单的情况下,用户实例化一个CsvReader
并一次性读取整个DataTable
,如下所示。这基本上是CsvFormReader
类在演示项目中使用的方法。
using (CsvReader reader = new CsvReader("MyFile.csv"))
{
bool hasHeader = true;
using (DataTable table = reader.ReadTable(hasHeader))
{
foreach (DataRow row in table.Rows)
{
foreach (DataColumn column in table.Columns)
{
string columnValue = (string)row[column];
}
string firstValue = (string)row["First"];
}
}
}
或者,用户可以完全绕过DataTable
并更直接地读取文件。以下代码演示了这种方法的一些方法:
using (CsvReader reader = new CsvReader("MyFile.csv"))
{
List columns = reader.ReadRow();
while (reader.ReadRowStart())
{
while (reader.HasColumn)
{
string columnValue = reader.ReadString();
}
reader.ReadRowEnd();
}
}
Windows开发者经常面临长时间运行操作的问题。解决这个问题的常见方法是使用BackgroundWorker
组件来执行这些长时间运行的操作。当使用这个组件时,通常需要报告进度。CsvReader
类公开了一个RowEnd
事件,用于此目的。每次读取完一行的末尾时,都会引发此事件。
CsvWriter
类通常提供了与CsvReader
等效的方法。例如,提供了WriteTable
方法来写入整个DataTable
。提供了WriteRow
、WriteRowStart
、Write
(一个列)和WriteRowEnd
方法,用于更直接地访问文件。
CsvFormWriter
类有这两种用法的示例。Write
方法为不同的数据类型提供了许多重载。如果没有适用的,就使用Write
方法的对象版本。此方法使用ToString
方法将数据转换为字符串,然后写入。
CsvReader
和CsvWriter
类都支持许多CSV文件格式的变体。主要是通过Options
属性来控制的,该属性的类型是CsvOption
。CsvOption
枚举指定了Flags
属性,因此可以组合多个选项,如下例所示:
reader.Options = CsvOption.Comment | CsvOption.CommentLine;
还提供了特殊字符的选项。例如,用户可以指定分隔列的字符。要读取包含制表符分隔值的文件,用户可能会这样做:
reader.EndColumnChar = '\t';
通常,这些选项和字符的属性应该在实例化后立即设置,并在使用CsvReader
或CsvWriter
之前。