Как вы reset курсор С#.NET TextReader вернулись к начальной точке?
У меня есть метод, который принимает либо экземпляр StringReader
(чтение из буфера обмена), либо экземпляр StreamReader
(чтение из файла), и в настоящее время выполняет листинг как один экземпляр TextReader
.
Мне нужно, чтобы он "предварительно прочитал" часть исходного ввода, затем reset верните курсор в начало. У меня нет оригинального имени файла. Как это сделать?
Существует упоминание метода Seek
System.IO.Stream
, но это не реализовано в TextReader
, хотя оно находится в StreamReader
через свойство Basestream
. Однако StringReader
не имеет свойства Basestream
Ответы
Ответ 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