FileHelpers - 当使用FieldQuoted属性时,文件中的额外列不会引发错误

时间:2014-07-29 05:40:20

标签: c# filehelpers

使用FileHelpers.dll版本3.0.1.0,带.net 4.0。

重现问题的代码:

像这样创建一个Accounts.txt文件:

"AccountName","ExtraColumn"
"MR GREEN ","abc"
"MR SMITH ","def"

c#帐户类:

[IgnoreFirst(1)]
[DelimitedRecord(",")]
[IgnoreEmptyLines()]
public class Account
{
    [FieldQuoted('"', QuoteMode.OptionalForBoth, MultilineMode.NotAllow)]
    public string AccountName;

}

要阅读文件:

        string fname = @"C:\test\Accounts.txt";

        FileHelperEngine engine = new FileHelperEngine(typeof(Account));

        Account[] importNodes =  (Account[])engine.ReadFile(fname);  // XX

现在,我原本期望在第XX行引发异常,因为文件(2)中的列数多于"帐户"中的列数。第(1)类。但是,没有引发异常,额外的列似乎被默默地忽略了。

如果您更改帐户类以删除" FieldQuoted"属性,然后确实引发了异常,如:

  

[FileHelpers.BadUsageException] {" Line:2 Column:0。Delimiter','   在最后一个字段' AccountName'之后找到(文件错了或你   需要在记录中添加一个字段   class)"} FileHelpers.BadUsageException

任何人都可以提供一些见解吗?具有FieldQuoted属性的代码是否确实会引发异常?我做错了吗?

编辑:是否有任何变通方法,以便在输入文件中的列数多于预期时会引发错误?

1 个答案:

答案 0 :(得分:6)

[IgnoreFirst(1)]忽略文件的第一行,而不是第一列。

请参阅此处的说明:IgnoreFirstAttribute

删除FieldQuoted会导致错误,因为您引用了没有此属性时无法正确处理的字段。

FileHelpers库只会忽略文件中没有相应字段的字段。

要忽略每行中的第一个字段,您只需在类定义中添加一个虚拟字段,如下所示:

[IgnoreFirst(1)]
[DelimitedRecord(",")]
[IgnoreEmptyLines()]
public class Account
{
   [FieldQuoted('"', QuoteMode.OptionalForBoth, MultilineMode.NotAllow)]
   public string AccountName;

   [FieldValueDiscarded]
   [FieldQuoted('"', QuoteMode.OptionalForBoth, MultilineMode.NotAllow)]
   public string Dummy;

}

作为一种解决方法,我可以建议在最后添加一个普通的string虚拟字段。然后,您可以检查FileHelperEngine.AfterReadRecord中是否填写了此字段,并抛出这样的异常:

FileHelperEngine engine = new FileHelperEngine(typeof(Account));
engine.AfterReadRecord += engine_AfterReadRecord;
try
{
    Account[] importNodes = (Account[])engine.ReadFile(fname);  // XX
}
catch (Exception e)
{

}


static void engine_AfterReadRecord(EngineBase engine, FileHelpers.Events.AfterReadEventArgs<object> e)
{
    if (!string.IsNullOrEmpty(((Account) e.Record).Dummy))
    {
        throw new ApplicationException("Unexpected field");
    }
}