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()的工作方式是将当前值传回,并读入下一行读取进行处理。那么会发生什么呢?
- 第一次调用ReadStream时,第一行已经被创建时由ForwardReader读入。
- currentLine由ForwardReader.ReadNextLine(),这是头记录
- IgnoreFirst设置设置,所以它调用ReadNextLine这又回到以前读取行,更新它的缓存,下一行。因此,由于我们跳过第1行,所以当前行成为第2行(ID 1)。
- 我们循环每一行,在通过ForwardReader.ReadNextLine()更新它之前将当前行添加到箭头。
- 一旦达到最大记录,我们退出。此时,currentLine是第4行(ID 3),缓存已经有第5行(ID 4)。
所以,如果你只是做了一个电话,一切都会好起来,这将是预期。但是,由于您拨打另一个电话,发生这种情况:
- 由于我们阅读了上面的内容,StreamReader已经在第6行的开头。
- 调用ReadStream创造了一个全新ForwardReader,进而自动读取下一个记录到它的缓冲,因而具有第6行(ID 5)
- 最大记录数为两个,所以我们也获得第7行(ID 6)
- 在这一点上,我们现在已经在当前缓冲区行8,缓存和StreamReader的列9等待在第10行
在某些方面,这是一个错误,但在别人的您的使用情况的ReadStream,这是不正确的。更好的方法是放弃要读取的最大记录数,如果需要按每个记录进行处理,则应使用INotifyRead/INotifyWrite功能。
我在FileHelpers github项目中提出了这个问题。 https://github.com/MarcosMeli/FileHelpers/issues/270 – netniV