65.9K
CodeProject 正在变化。 阅读更多。
Home

灵活的带进度报告的 CSV 读写器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2011 年 8 月 3 日

CPOL

4分钟阅读

viewsIcon

36408

downloadIcon

2987

灵活的带进度报告的 CSV 读写器,支持多种文件格式变体。

CsvTest.png

引言

随着时间的推移,我经常需要读取和写入 CSV(逗号分隔值)文件。虽然大多数 CSV 文件遵循相当标准的格式,但在此基础上存在许多变体。一些常见的变体包括制表符分隔值文件、带有标题行的文件、引用规则的变化以及支持注释字符/行的文件。

本文介绍的类简化了许多不同格式变体的读写。代码和本文中的 CSV 指的是字符分隔值(其中逗号分隔值是其子类)。

虽然演示项目允许显示和操作几种常见的 CSV 变体,但它并未演示包含类所有功能。

尽管如今 XML 文件在日常使用中经常取代 CSV 文件,但 CSV 仍然是这种文件格式的紧凑且简单的替代方案。许多不同的应用程序,包括 Excel,都能够读写这些文件。

背景

在学习代码时,用户应重点关注 CsvFormBaseCsvFormReaderCsvFormWriter 类,它们提供了一些简单的代码使用示例。用户界面代码很长,与本文关系不大。然而,它确实演示了一些相关主题,例如 DataGridView 控件和 BackgroundWorker 组件。

此外,MainForm 类中的 mainBackgroundWorker_DoWorkmainBackgroundWorker_ProgressChangedmainBackgroundWorker_RunWorkerCompleted 方法对于需要报告 CSV 文件读写期间进度的开发人员来说可能特别有用。

Using the Code

此库中的主要类是 CsvReaderCsvWriter。由于代码固有的灵活性,它们支持大量方法。代码本身已完全注释,是大多数这些方法信息的最佳来源。本文仅描述一些更常见的用法。

使用 CsvReader 读取

最简单的方法是,用户实例化一个 CsvReader 并一次性读取整个 DataTable,如下所示。这本质上是演示项目中 CsvFormReader 类中使用的方​​法。

// Using a CSV reader for the file MyFile.csv...
using (CsvReader reader = new CsvReader("MyFile.csv"))
{
  // Indicate the file has a header row
  bool hasHeader = true;

  // Using a data table read by the reader...
  using (DataTable table = reader.ReadTable(hasHeader))
  {
    // Loop through all of the rows...
    foreach (DataRow row in table.Rows)
    {
      // Loop through all of the columns...
      foreach (DataColumn column in table.Columns)
      {
        // Get the column value for this row
        string columnValue = (string)row[column];
      } // Loop through all of the columns...

      // Get the value for the column named "First"
      string firstValue = (string)row["First"];
    } // Loop through all of the rows...
  } // Using a data table read by the reader...
} // Using a CSV reader for the file MyFile.csv...

或者,用户可以完全绕过 DataTable,更直接地读取文件。以下代码演示了此方法的某些方法

// Using a CSV reader for the file MyFile.csv...
using (CsvReader reader = new CsvReader("MyFile.csv"))
{
  // Read an entire row into a list
  List<string> columns = reader.ReadRow();

  // While more rows remain...
  while (reader.ReadRowStart())
  {
    // While more columns remain...
    while (reader.HasColumn)
    {
      // Get the next column value
      string columnValue = reader.ReadString();
    } // While more columns remain...

    // Read the end of the row
    reader.ReadRowEnd();
  } // While more rows remain...
} // Using a CSV reader for the file MyFile.csv...

Windows 开发人员经常面临的问题是长期运行的操作。解决此问题的常用方法是使用 BackgroundWorker 组件执行这些长期运行的操作。使用此组件时,通常需要报告进度。CsvReader 类公开了一个 RowEnd 事件用于此目的。每次读取完一行时都会引发该事件。

使用 CsvWriter 写入

CsvWriter 类通常提供与其 CsvReader 相对应的等效方法。例如,提供了 WriteTable 方法来写入整个 DataTable。提供了 WriteRowWriteRowStartWrite(一个列)和 WriteRowEnd 方法以更直接地访问文件。

CsvFormWriter 类包含了这两种用法的示例。

Write 方法提供了许多不同数据类型的重载。如果没有适用的重载,则使用对象的 Write 方法。此方法使用 ToString 方法在写入之前将其转换为字符串。

文件格式变体

CsvReaderCsvWriter 类都支持 CSV 文件格式的许多变体。这主要通过 Options 属性控制,该属性的类型为 CsvOptionCsvOption 枚举指定了 Flags 属性,因此可以组合多个选项,如以下示例

reader.Options = CsvOption.Comment | CsvOption.CommentLine;

此外,还提供了特殊字符的选项。例如,用户可以指定分隔列的字符。例如,要读取包含制表符分隔值的文件,用户可以这样做

reader.EndColumnChar = '\t';

通常,应在实例化 CsvReaderCsvWriter 后立即设置这些选项和字符的属性,然后在开始使用它们之前。

关注点

由于选项/方法的组合范围异常广泛,加上我工作的时间限制,我没有测试每一种可能的组合。我有点自私,只测试了我在演示项目中使用的部分以及我个人需要的部分。希望我在测试中没有遗漏太多内容,但如果遗漏了您(读者)在意的内容,我提前表示歉意。

历史

  • 2011 年 8 月 3 日 - 原始版本。
© . All rights reserved.