2014-09-15 2 views
2

У меня есть устройство чтения строк по строке (sr.ReadLine()). Мой код подсчитывает конец строки с обоими строками \r\n и/или \n.Считывание потока строки

 StreamReader sr = new System.IO.StreamReader(sPath, enc); 

     while (!sr.EndOfStream) 
     { 
      // reading 1 line of datafile 
      string sLine = sr.ReadLine(); 
      ... 

Как сказать код (вместо универсального sr.ReadLine()), что я хочу, чтобы подсчитать новую строку только полный \r\n и не \n?

+0

Итак, вы хотите количество вхождений '\ r \ n' и числа вхождений соло' \ n' в поток? – Axarydax

+0

Точно я хочу прочитать каждую строку, но строка означает, что она заканчивается полным '\ r \ n', а не только' \ n'. Другими словами, я могу сказать, что одна строка может содержать любые «blah blah \ n blah \ r \ n' – procma

+0

Важно знать, насколько велик ваш файл, чтобы выбрать правильный способ обработки ввода. – Steve

ответ

4

Это невозможно сделать с помощью StreamReader.ReadLine. Согласно msdn:

линия определяется как последовательность символов с последующим переводом строки («\ п»), возврат каретки («\ г»), или возврата каретки немедленно с последующим по строке («\ r \ n»). Возвращаемая строка не содержит , содержащую завершающий возврат каретки или линию. Возвращаемое значение равно NULL, если достигнут конец входного потока.

Так yoг должны читать этот поток байт в байт и обратной линии, только если вы захватили \ г \ п

EDIT

Вот некоторые примеры кода

private static IEnumerable<string> ReadLines(StreamReader stream) 
{ 
    StringBuilder sb = new StringBuilder(); 

    int symbol = stream.Peek(); 
    while (symbol != -1) 
    { 
     symbol = stream.Read(); 
     if (symbol == 13 && stream.Peek() == 10) 
     { 
      stream.Read(); 

      string line = sb.ToString(); 
      sb.Clear(); 

      yield return line; 
     } 
     else 
      sb.Append((char)symbol); 
    } 

    yield return sb.ToString(); 
} 

Вы можете использовать его как

foreach (string line in ReadLines(stream)) 
{ 
    //do something 
} 
+0

Да, я боялся из этого :(Можете ли вы представить образец, чтобы отправить свои анкеты pls? – procma

2

вы не можете сделать это с ReadLine, но вы можете сделать вместо этого:

stream.ReadToEnd().Split(new[] {"\r\n"}, StringSplitOptions.None) 
+0

Что делать, если данные потока действительно велики? ReadToEnd не кажется разумным решением. –

+0

всегда зависит от рабочей нагрузки, если вам нужно супер оптимизировать, вы можете использовать [StreamReader.Readline источник моно реализации] (https://github.com/mono/mono/blob/master/mcs/class/corlib/System.IO/StreamReader.cs) –

-1

Для упрощения, давайте работать над байтовый массив:

static int NumberOfNewLines(byte[] data) 
    { 
     int count = 0; 
     for (int i = 0; i < data.Length - 1; i++) 
     { 
      if (data[i] == '\r' && data[i + 1] == '\n') 
       count++; 
     } 
     return count; 
    } 

Если вы заботитесь об эффективности, оптимизации прочь, но это должно сработать.

Вы можете получить байты файла, используя System.IO.File.ReadBytes(string filename).

+0

не использовать байт [] непосредственно для текста, потому что кодирование может создавать проблемы –

+0

@EnricoSada так есть какой-то способ, что в unicode/utf8 эти байты (\ n, \ r) будут просто частью многобайтовых символов? – Axarydax

Смежные вопросы