StreamReader.ReadLine()行为很奇怪

时间:2018-09-28 22:49:48

标签: c# stream

我有一个带有几千行的定界文件,并且编写了一种自动检测定界符的方法。

方法如下:

private bool TryDetermineDelimiter(FileInfo target, out char delimiter)
        {
            char[] possibleDelimiters = new char[] { ',', ';', '-', ':' };

            using (StreamReader sr = new StreamReader(target.OpenRead()))
            {
                List<int> delimiterHits = new List<int>();

                foreach (char del in possibleDelimiters)
                {


                    while (!sr.EndOfStream)
                    {
                        var line = sr.ReadLine();
                        var matches = Regex.Matches(line, $"{del}(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");

                        if(matches.Count == 0)
                        {
                            sr.BaseStream.Seek(0, SeekOrigin.Begin);
                            break;
                        }

                        delimiterHits.Add(matches.Count);
                    }

                    if (delimiterHits.Any(d => d != delimiterHits[0]) || delimiterHits.Count == 0)
                    {
                        delimiterHits.Clear();
                        continue;
                    }

                    delimiter = del;
                    return true;
                }
            }

            delimiter = ',';
            return false;
        }

发生了一件奇怪的事情,在第5行,对sr.ReadLine()的调用返回了第5行,其中第1行已连接

例如:

定界文件:

col1; col2; col3; col4
val1; val2; val3; val4
val5; val6; val7; val8
...

StreamReader.ReadLine()的前4个调用返回期望的行,但第5个调用返回:val13; val14; val15; val16; col1; col2; col3; col4;

逐步完成,我可以确认循环永远不会进入if(matches.Count == 0)块,每次迭代都找到正确数量的定界符。

不幸的是,我无法发布 actual 文件的内容,因为它可能会给我带来麻烦,但是我已经确保行尾没有繁琐的业务或其他字符。该文件符合预期。

我还应该提到,使用逗号分隔的值不会发生此错误,只会出现分号

1 个答案:

答案 0 :(得分:2)

将代码更改为此

if (matches.Count == 0)
{
    sr.BaseStream.Seek(0, SeekOrigin.Begin);
    sr.DiscardBufferedData();
    break;
}

通过指示StreamReader丢弃其缓冲区,即指示其与实际基本流进行同步。

除此之外,返回的行没有串联,但是它循环返回自己,尽管我上面显示的内容可以解决此问题