Как подсчитать количество байтов, прочитанных TextReader.ReadLine ()? - PullRequest
3 голосов
/ 03 июня 2010

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

Я написал следующее:

using (TextReader myTextReader = CreateTextReader())
{
    string record = myTextReader.ReadLine();
    bytesRead += record.Length;
    ParseRecord(record);
}

Однако это не работает, поскольку ReadLine() удаляет все символы CR / LF в строке. Кроме того, строка может заканчиваться символами CR, LF или CRLF, что означает, что я не могу просто добавить 1 к bytesRead.

Есть ли простой способ получить фактическую длину строки, или я пишу свой собственный метод ReadLine() в терминах гранулярных операций Read()?

Ответы [ 3 ]

2 голосов
/ 03 июня 2010

Получение текущей позиции базового потока не поможет, так как StreamReader будет буферизировать данные, прочитанные из потока.

По сути, вы не можете сделать это без написания собственного StreamReader. Но тебе действительно нужно?

Я бы просто посчитал количество прочитанных строк.

Конечно, это означает, что для позиционирования на определенной строке вам нужно будет читать N строк, а не просто искать смещение, но что с этим не так? Вы определили, что производительность будет неприемлемой?

1 голос
/ 03 июня 2010

TextReader читает строки, которые являются символами, которые [в зависимости от кодировки] не равны байтам.

Как насчет того, чтобы просто сохранить количество прочитанных строк и просто пропустить столько строк при восстановлении? Я предполагаю, что все дело в том, чтобы не обрабатывать эти строки, не обязательно избегать их чтения из потока.

0 голосов
/ 03 июня 2010

Если подумать, я могу использовать StreamReader и получить текущую позицию основного потока следующим образом.

using (StreamReader myTextReader = CreateStreamReader())
{
    stringRecord = myTextReader.ReadLine();
    bytesRead += myTextReader.BaseStream.Position;
    ParseRecord(record);
    // ...
}
...