StreamReader.ReadLine () очень странное поведение - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть файл с разделителями с несколькими тысячами строк, и я написал метод для автоматического определения разделителя.

Метод выглядит следующим образом:

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-й строкой

Так, например:

с разделителямиfile:

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

Первые 4 вызова на StreamReader.ReadLine() возвращают ожидаемые строки , но возвращает 5-й вызов: val13; val14; val15; val16; col1; col2; col3; col4;

Проходя, я могу подтвердитьчто цикл никогда не входит в блок if(matches.Count == 0), правильное количество разделителей находится на каждой итерации.

К сожалению, я не могу опубликовать содержимое фактического файла, потому что он может получить меняв беде, но я гарантировал , что нет никаких сомнительных дел с окончаниями строк или другими символами.Файл, как и ожидалось.

Я должен также упомянуть, что эта ошибка не возникает с запятыми разделенными значениями, только с точками с запятой .

1 Ответ

0 голосов
/ 29 сентября 2018

Измените свой код на этот

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

Указывая StreamReader сбросить свой буфер, вы указываете ему синхронизироваться с фактическим базовым потоком.

Кроме этоговозвращенные строки не объединяются, но они возвращаются в исходное состояние, хотя то, что я показал выше, исправит это

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...