У меня есть файл с разделителями с несколькими тысячами строк, и я написал метод для автоматического определения разделителя.
Метод выглядит следующим образом:
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)
, правильное количество разделителей находится на каждой итерации.
К сожалению, я не могу опубликовать содержимое фактического файла, потому что он может получить меняв беде, но я гарантировал , что нет никаких сомнительных дел с окончаниями строк или другими символами.Файл, как и ожидалось.
Я должен также упомянуть, что эта ошибка не возникает с запятыми разделенными значениями, только с точками с запятой .