【问题标题】:FileHelpers library escape separator when reading Stream读取 Stream 时的 FileHelpers 库转义分隔符
【发布时间】:2015-06-20 21:38:56
【问题描述】:

需要帮助来弄清楚如何处理以下场景。

我们有一个使用 FileHelpers 库来解析 CSV 文件的 .NET 应用程序。 我们不使用物理文件,而是使用 SQL 服务器数据库,其中 CSV 文件存储在 VARBINARY 字段中。我们要做的是使用流阅读器读取二进制内容,并使用适当的多记录引擎对其进行解析。

我们的 CSV 文件使用分号 (;) 作为分隔符,但文件记录可能包含转义分隔符,其中转义字符是感叹号 (!)。 解析文件时必须忽略转义的分隔符。 这意味着必须以相同的方式解析以下记录:

Hello;World;Foo //这里没有转义分隔符

你好!;;世界;Foo!; //这里有两个转义分隔符

前面例子的两个记录都是有效的,并且必须产生一个属性为“Hello”、“World”和“Foo”的对象。

使用同一网站上一个问题的答案 (FileHelper escape delimiter) 我尝试使用事件处理程序订阅 MultiRecordEngine 类的公共事件 BeforeReadRecord,该事件处理程序只需替换所有出现的“!;”带空字符串。

这在使用 MultiRecordEngine.ReadString 方法时效果很好:每次读取记录时都会触发事件 BeforeReadRecord,按预期调用事件处理程序,并将转义的分隔符替换为空字符串。

不幸的是,当使用 MultiRecordEngine 从流中读取时,根本不会触发事件 BeforeReadRecord 并且永远不会执行事件处理程序代码。 我想从流中读取时没有办法利用 BeforeReadRecord 事件。

根据 FileHelpers 库文档 (http://filehelpers.sourceforge.net/FileHelpers.MultiRecordEngineMembers.html),在这种情况下似乎没有合适的事件。

有人知道从流中读取时处理转义分隔符的方法吗?

感谢您的帮助。

恩里科。

【问题讨论】:

  • 一种可能的解决方案是实现自定义编码。参考this Q/A

标签: c# csv filehelpers


【解决方案1】:

无论你使用的是ReadFile(string fileName)ReadString(string source)还是ReadStream(TextReader reader),它都使用相同的底层函数@ 987654324@ 解析数据。引擎必须知道它应该通过 MustNotifyRead 属性通知读取。该属性的代码如下:

return BeforeReadRecord != null ||
       AfterReadRecord != null ||
       RecordInfo.NotifyRead;

这基本上意味着您必须订阅 BeforeRecordRecordAfterRecordRecord 事件,或者拥有 INotifyRead您正在阅读之前它通过 OnBeforeReadRecord(e); 尝试任何通知,它只有以下代码:

if (RecordInfo.NotifyRead)
    ((INotifyRead)e.Record).BeforeRead(e);

if (BeforeReadRecord != null)
    BeforeReadRecord(this, e);

return e.SkipThisRecord;

这基本上意味着,如果您在记录类上有 INotifyRead,它会调用 INotifyRead.BeforeRead() 方法和/或 BeforeReadRecord 订阅任何内容时的事件。

但是,由于您使用的是动态选择器,我认为它不会检查所选记录类,而是检查构造函数中的第一种记录类型,因此如果您尝试实现 INotifyRead。如果你这样做了,并且你想忽略基类属性,你应该在类级别设置适当的忽略属性。

【讨论】:

  • 需要注意的一点是,我将其与 FileHelpers v3.2.5 进行比较
猜你喜欢
  • 2020-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多