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

Tony Selke 的 TextFieldParser 的修改版 C# 实现

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.31/5 (20投票s)

2005年2月27日

2分钟阅读

viewsIcon

108056

downloadIcon

966

这是 Tony Selkes 提交的 TextFieldParser 的 C# 实现,它包括将模式放在 XML 文件中并将数据直接加载到 DataTable 的功能。

Application after parsing 1,500,000 fields.

引言

有一天,我在浏览 Code Project 时,发现了 Tony Selke 的一篇优秀文章 '用于解析固定宽度或分隔符文本文件的包装类'。我决定将其代码移植到 C#,因为这是我选择的语言。在此过程中,我还添加了一些功能

  1. 我添加了将文本文件的模式放在 XML 文件中的功能。
  2. 我添加了将文本文件直接解析到 DataTable 的功能。

这是我提交给 Code Project 的第一篇文章,所以请温柔对待。

它能做什么?

该库可以导入分隔符或固定宽度文件,而开发者可以通过订阅 RecordFound 事件来决定对每个记录做什么。该库可以直接将分隔符或固定宽度文件导入到 DataTable 中。

它是如何工作的?

开发者可以使用代码或 XML 模式文件设置模式。这将确定将在 DataTable 中使用的DataType。根据模式,文本值将被解析并转换为相应的DataType,并将其放入 DataTable 或作为事件简单地传递给调用对象。

使用代码

首先,添加对库的引用。然后在源文件的顶部添加 using 语句。

using WhaysSoftware.Utilities.FileParsers;

创建 TextFieldParser 对象的实例。

TextFieldParser tfp = new TextFieldParser(filePath);

如果您将使用 XML 模式文件,请使用具有“schemaFile”参数的构造函数。

TextFieldParser tfp = new TextFieldParser(filePath, schemaPath);

如果使用 XML 模式文件,以下是如何显示 XML 模式文件的示例

<TABLE Name="TEST" FileFormat="Delimited" ID="Table1">
    <FIELD Name="LineNumber" DataType="Int32" />
    <FIELD Name="Quoted String" DataType="String" Quoted="true" />
    <FIELD Name="Unquoted String" DataType="String" Quoted="false" />
    <FIELD Name="Double" DataType="Double" />
    <FIELD Name="Boolean" DataType="Boolean" />
    <FIELD Name="Decimal" DataType="Decimal" />
    <FIELD Name="DateTime" DataType="DateTime" />
    <FIELD Name="Int16" DataType="Int16" />
</TABLE>

我已经在源代码中包含了对模式文件属性的完整描述。这是一个相同的示例,但是是用代码完成的。

TextFieldCollection fields = new TextFieldCollection();
fields.Add(new TextField("Line Number", TypeCode.Int32));
fields.Add(new TextField("Quoted String", TypeCode.String, true));
fields.Add(new TextField("Unquoted String", TypeCode.String, false));
fields.Add(new TextField("Double", TypeCode.Double));
fields.Add(new TextField("Boolean", TypeCode.Boolean));
fields.Add(new TextField("Decimal", TypeCode.Decimal));
fields.Add(new TextField("DateTime", TypeCode.DateTime));
fields.Add(new TextField("Int16", TypeCode.Int16));
tfp.TextFields = fields;

现在,如果您想对记录执行自定义操作,可以订阅 RecordFound 事件……

tfp.RecordFound += new RecordFoundHandler(tfp_RecordFound);
tfp.ParseFile();
...
private void tfp_RecordFound(ref int CurrentLineNumber, 
                                         TextFieldCollection TextFields)
{
    //Do something with the TextFields parameter
}

或者您可以调用 ParseToDataTable 以在 DataTable 中获取结果。

DataTable dt = tfp.ParseToDataTable();

注意:即使调用 ParseToDataTableRecordFound 事件仍然会被触发。

您还可以订阅 RecordFailed 事件以获取记录解析失败的通知。在事件处理程序中,您可以决定是否可以继续。

tfp.RecordFailed += new RecordFailedHandler(tfp_RecordFailed);
...
private void tfp_RecordFailed(ref int CurrentLineNumber, 
        string LineText, string ErrorMessage, ref bool Continue)
{
    MessageBox.Show("Error: " + ErrorMessage + Environment.NewLine + 
                            "Line: " + LineText);
}

就是这样。我期待着大家的评论和建议。

历史

  • 02/27/2005

    初始发布。

© . All rights reserved.