¿Cómo se restablece un C#.NET TextReader cursor volver al punto de inicio?
Tengo un método que toma una instancia StringReader
(leyendo desde el portapapeles) o una instancia StreamReader
(leyendo desde un archivo) y, en la actualidad, proyecta cualquiera de ellas como una instancia TextReader
.
Lo necesito para 'pre-leer' parte de la entrada de origen, luego restablecer el cursor al inicio. No tengo necesariamente el nombre de archivo original. ¿Cómo hago esto?
Se menciona el método Seek
de System.IO.Stream
pero esto no se implementa en TextReader
, aunque está en StreamReader
a través del Basestream
propiedad. Sin embargo StringReader
no tiene una propiedad BaseStream
4 answers
Depende del TextReader
. Si es un StreamReader
, puedes usar:
sr.BaseStream.Position = 0;
sr.DiscardBufferedData();
(Suponiendo que el flujo subyacente es buscable, por supuesto.)
Otras implementaciones de TextReader
no pueden tener un concepto de "rebobinar", de la misma manera que IEnumerable<T>
no. En muchos sentidos puedes pensar en TextReader
como un IEnumerable<char>
glorificado. Tiene métodos para leer trozos enteros de datos a la vez, leer líneas, etc., pero es fundamentalmente un tipo de "lectura directa".
EDITAR: No creo que StringReader
soporte cualquier tipo de rebobinado-sería mejor recrear el StringReader
de la cadena original, si puede. Si eso no es factible, siempre puede crear su propia clase TextReader
que proxy todas las llamadas "normales" a otro StringReader
, pero recrea esa instancia de proxy cuando es necesario.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-06 20:46:14
Si es un StreamReader
, y si esa corriente soporta la búsqueda, entonces:
reader.BaseStream.Seek(0, SeekOrigin.Begin);
reader.DiscardBufferedData();
Sin embargo, esto no es posible en TextReader
s arbitrarios. Tal vez podría leer todo como una cadena, entonces se puede utilizar StringReader
repetidamente?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-25 11:47:19
Me encontré con su post, y estaba bastante decepcionado de que esto no es posible. Hackeé algo rápido que funciona: simplemente evita el stringreader por completo:
Stream stream = new MemoryStream((new System.Text.ASCIIEncoding().GetBytes(mystring)), false);
reader = new StreamReader(stream, new System.Text.ASCIIEncoding());
No es bonito, y utiliza ASCII (que era lo que necesitaba de todos modos). Tenga en cuenta que con una codificación diferente esto no funcionará, ya que buscará el n'ésimo byte que no tiene que ser igual al n'ésimo carácter. Si usted necesita que usted podría hacer algo como
Stream stream = new MemoryStream((new System.Text.UTF32Encoding().GetBytes(mystring)), false);
reader = new StreamReader(stream, new System.Text.UTF32Encoding());
Como UTF32 es el único unicode de longitud fija formato.
Ahora puedes hacer
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();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-09 13:11:41
Buscad y hallaréis.
Seek(0, SeekOrigin.Begin);
TextReader
se deriva de StreamReader
. StreamReader
contiene una propiedad BaseStream
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-17 08:17:55