Подтвердить что ты не робот

Как вы reset курсор С#.NET TextReader вернулись к начальной точке?

У меня есть метод, который принимает либо экземпляр StringReader (чтение из буфера обмена), либо экземпляр StreamReader (чтение из файла), и в настоящее время выполняет листинг как один экземпляр TextReader.

Мне нужно, чтобы он "предварительно прочитал" часть исходного ввода, затем reset верните курсор в начало. У меня нет оригинального имени файла. Как это сделать?

Существует упоминание метода Seek System.IO.Stream, но это не реализовано в TextReader, хотя оно находится в StreamReader через свойство Basestream. Однако StringReader не имеет свойства Basestream

4b9b3361

Ответ 1

Это зависит от TextReader. Если это a StreamReader, вы можете использовать:

sr.BaseStream.Position = 0;
sr.DiscardBufferedData();

(Предположим, что основной поток доступен для поиска, конечно.)

Другие реализации TextReader могут не иметь понятия "перемотки", так же, как IEnumerable<T>. Во многом вы можете думать о TextReader как прославленный IEnumerable<char>. Он имеет методы для чтения целых фрагментов данных за раз, чтение строк и т.д., Но в основном это "тип прямого чтения".

EDIT: Я не верю, что StringReader поддерживает любую перемотку - вам лучше было бы воссоздать StringReader из исходной строки, если можно. Если это невозможно, вы всегда можете создать свой собственный класс TextReader, который проксирует все "обычные" вызовы на другой StringReader, но воссоздает этот экземпляр прокси, когда это необходимо.

Ответ 2

Если это StreamReader, и если этот поток поддерживает поиск, тогда:

        reader.BaseStream.Seek(0, SeekOrigin.Begin);
        reader.DiscardBufferedData();

Однако это невозможно для произвольных TextReader s. Вы могли бы прочитать все это как строку, затем вы можете использовать StringReader несколько раз?

Ответ 3

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

Stream stream = new MemoryStream((new System.Text.ASCIIEncoding().GetBytes(mystring)), false);
reader = new StreamReader(stream, new System.Text.ASCIIEncoding());

Это не очень красиво, и он использует ASCII (это было то, что мне было нужно). Обратите внимание, что с другой кодировкой это не будет работать, так как вы будете искать n-й байт, который не будет равен n-му символу. Если вам нужно, чтобы вы могли сделать что-то вроде

Stream stream = new MemoryStream((new System.Text.UTF32Encoding().GetBytes(mystring)), false);
reader = new StreamReader(stream, new System.Text.UTF32Encoding());

поскольку UTF32 является единственным форматом Unicode фиксированной длины.

Теперь вы можете сделать

reader.BaseStream.Position = wherever; // or wherever * 4 for the UTF32 variety,
                                       // in your case, the beginning of the string,
                                       // which is always 0 obviously
reader.DiscardBufferedData();

Ответ 4

Ищите, и вы найдете.

Seek(0, SeekOrigin.Begin);

TextReader получен из StreamReader. StreamReader содержит свойство BaseStream