read example c# stream

example - streamreader excel c#



StreamReader sin bĂșfer (2)

Bueno, puedes usar Stream.Seek para establecer la posición de la transmisión. Me parece que el problema que tienes aquí es que StreamReader lee caracteres en lugar de bytes (que, dependiendo de la codificación, puede ser diferente de 1 byte por carácter). Desde la biblioteca de MSDN :

StreamReader está diseñado para la entrada de caracteres en una codificación particular, mientras que la clase Stream está diseñada para entrada y salida de bytes.

Cuando llama a reader.ReadToEnd (), lee los datos como una cadena de caracteres en función de la codificación que utiliza. Es posible que tengas mejor suerte con el método Stream.Read . Lea sus datos de cadena con StreamReader y luego extraiga los datos binarios en un byte [] cuando haya leído en el encabezado que le notifica los datos binarios entrantes.

¿Hay alguna manera de evitar que StreamReader realice un almacenamiento en memoria intermedia?

Estoy tratando de manejar el resultado de un Proceso que puede ser binario o de texto. La salida se verá como una respuesta HTTP, por ejemplo

Content-type: application/whatever Another-header: value text or binary data here

Lo que quiero hacer es analizar los encabezados usando un StreamReader , y luego leer desde su BaseStream o el StreamReader para manejar el resto del contenido. Aquí es básicamente con lo que comencé:

private static readonly Regex HttpHeader = new Regex("([^:]+): *(.*)"); private void HandleOutput(StreamReader reader) { var headers = new NameValueCollection(); string line; while((line = reader.ReadLine()) != null) { Match header = HttpHeader.Match(line); if(header.Success) { headers.Add(header.Groups[1].Value, header.Groups[2].Value); } else { break; } } DoStuff(reader.ReadToEnd()); }

Esto parece destruir datos binarios. Así que cambié la última línea a algo como esto:

if(headers["Content-type"] != "text/html") { // reader.BaseStream.Position is not at the same place that reader // makes it looks like it is. // i.e. reader.Read() != reader.BaseStream.Read() DoBinaryStuff(reader.BaseStream); } else { DoTextStuff(reader.ReadToEnd()); }

... pero StreamReader almacena su entrada, por lo que reader.BaseStream está en la posición incorrecta. ¿Hay alguna forma de desactivar el StreamReader? ¿O puedo decirle a StreamReader que restablezca la transmisión de regreso a donde está StreamReader?


Esta respuesta es tardía y posiblemente ya no sea relevante para usted, pero puede ser útil para otra persona que tropieza con este problema.

Mi problema involucraba archivos PPM , que tienen un formato similar de:

  • Texto ASCII al principio
  • Bytes binarios para el resto del archivo

El problema que me encontré fue que la clase StreamReader es incapaz de leer cosas de un byte a la vez sin almacenar en el búfer. Esto causó resultados inesperados en algunos casos, ya que el método Read() lee un solo carácter, no un solo byte.

Mi solución fue escribir un contenedor alrededor de una secuencia que leería los bytes uno a la vez. El contenedor tiene 2 métodos importantes, ReadLine() y Read() .

Estos 2 métodos me permiten leer las líneas ASCII de una secuencia, sin búfer, y luego leer un solo byte a la vez para el resto de la secuencia. Es posible que deba hacer algunos ajustes para satisfacer sus necesidades.

class UnbufferedStreamReader: TextReader { Stream s; public UnbufferedStreamReader(string path) { s = new FileStream(path, FileMode.Open); } public UnbufferedStreamReader(Stream stream) { s = stream; } // This method assumes lines end with a line feed. // You may need to modify this method if your stream // follows the Windows convention of /r/n or some other // convention that isn''t just /n public override string ReadLine() { List<byte> bytes = new List<byte>(); int current; while ((current = Read()) != -1 && current != (int)''/n'') { byte b = (byte)current; bytes.Add(b); } return Encoding.ASCII.GetString(bytes.ToArray()); } // Read works differently than the `Read()` method of a // TextReader. It reads the next BYTE rather than the next character public override int Read() { return s.ReadByte(); } public override void Close() { s.Close(); } protected override void Dispose(bool disposing) { s.Dispose(); } public override int Peek() { throw new NotImplementedException(); } public override int Read(char[] buffer, int index, int count) { throw new NotImplementedException(); } public override int ReadBlock(char[] buffer, int index, int count) { throw new NotImplementedException(); } public override string ReadToEnd() { throw new NotImplementedException(); } }