FileHelpers:使用ReadStream旁路两项纪录在每次迭代

问题描述:

我有一个文件中定义这样FileHelpers:使用ReadStream旁路两项纪录在每次迭代

ID TEXT 
1 XXXX 
2 XXXX 
3 XXXX 
4 XXXX 
5 XXXX 
6 XXXX 
7 XXXX 
8 XXXX 
9 XXXX 
10 XXXX 

和类像这样

[DelimitedRecord("\t")] 
    public class TestItem 
    { 
     public int Id; 
     public string Text; 
    } 

定义的filehelper我用下面的读取文件代码

FileHelperEngine<TestItem> eng = new FileHelperEngine<TestItem>(); 
      using (var file = new FileStream("FILEPATH", FileMode.Open, FileAccess.Read)) 
      { 
       //I've declared like this because filehelper close the reader after each iteration 
       StreamReader reader = new StreamReader(file, Encoding.UTF8, false, 1024, true); 
       eng.Options.IgnoreFirstLines = 1; 

       TestItem[] content = null; 
       bool headerRead = false; 
       do 
       { 
        content = eng.ReadStream(reader, 2); 
        if (!headerRead) 
        { 
         headerRead = true; 
         eng.Options.IgnoreFirstLines = 0; 
        } 
       } 
       while (!reader.EndOfStream); 
      } 

如您所见,每次读取2条记录,并在第一条记录中忽略firl行关合作。 但在第二次迭代时,我期待获得第3条记录和第4条记录,但是,我收到了第5条和第6条记录。为什么这样? 如何解决这个问题?

问题在于您使用ReadStream函数。它旨在读取最大记录数的文件,然后关闭。因此,它在每次调用时重新创建一个ForwardReader。

ForwardReader.ReadNextLine()的工作方式是将当前值传回,并读入下一行读取进行处理。那么会发生什么呢?

  1. 第一次调用ReadStream时,第一行已经被创建时由ForwardReader读入。
  2. currentLine由ForwardReader.ReadNextLine(),这是头记录
  3. IgnoreFirst设置设置,所以它调用ReadNextLine这又回到以前读取行,更新它的缓存,下一行。因此,由于我们跳过第1行,所以当前行成为第2行(ID 1)。
  4. 我们循环每一行,在通过ForwardReader.ReadNextLine()更新它之前将当前行添加到箭头。
  5. 一旦达到最大记录,我们退出。此时,currentLine是第4行(ID 3),缓存已经有第5行(ID 4)。

所以,如果你只是做了一个电话,一切都会好起来,这将是预期。但是,由于您拨打另一个电话,发生这种情况:

  1. 由于我们阅读了上面的内容,StreamReader已经在第6行的开头。
  2. 调用ReadStream创造了一个全新ForwardReader,进而自动读取下一个记录到它的缓冲,因而具有第6行(ID 5)
  3. 最大记录数为两个,所以我们也获得第7行(ID 6)
  4. 在这一点上,我们现在已经在当前缓冲区行8,缓存和StreamReader的列9等待在第10行

在某些方面,这是一个错误,但在别人的您的使用情况的ReadStream,这是不正确的。更好的方法是放弃要读取的最大记录数,如果需要按每个记录进行处理,则应使用INotifyRead/INotifyWrite功能。

+0

我在FileHelpers github项目中提出了这个问题。 https://github.com/MarcosMeli/FileHelpers/issues/270 – netniV