2010-04-03 33 views
8

tengo un métodoStreamReader.ReadToEnd() devuelve una cadena vacía

private static String DecompressAndDecode(byte[] data) 
{ 
    GZipStream decompressor = new GZipStream(new MemoryStream(data), CompressionMode.Decompress); 
    StreamReader decompressed = new StreamReader(decompressor, Encoding.UTF8); 
    String result = decompressed.ReadToEnd(); 
    return result; 
} 

tengo un poco de texto gzipped como entrada y el resultado se supone que es una representación de cadena de este texto. El problema es que el método devuelve una cadena vacía. Lo que me desconcierta es que cuando paso por el método en modo de depuración y llego a la declaración de devolución la variable de resultado es una cadena vacía, pero si creo un reloj para la expresión descompressed.ReadToEnd() me devuelve el texto. Lo que esperaría en este punto es la variable de resultado para contener el texto y la expresión descompressed.ReadToEnd() evaluando una cadena vacía. (Reevaluando la expresión descomprimida.ReadToEnd() devuelve una cadena vacía como se esperaba).

@Edit: he encontrado que en mi caso ReadToEnd() devuelve el texto en la segunda llamada devolver cadenas vacías en la primera llamada y después de la segunda llamada.

Debe haber algo obvio que me falta aquí.

+0

¿La codificación es realmente UTF8? –

+0

Sí, es UTF8. – axk

Respuesta

21

Creo que su problema es la posición de la aguja en el vapor. Cada vez que realiza el ReadToEnd, el puntero se establece hasta el final y es por eso que puede verlo por primera vez.

Ejecute el siguiente código antes de ReadToEnd para establecer el puntero al principio. someStream.Seek(0, SeekOrigin.Begin)

+0

Esto resolvió el problema para mí – Aaronontheweb

+0

No existe Seek función miembro de StreamReader. – stackptr

+0

@stackptr se necesita usarlo en la transmisión que alimenta a su streamReader –

1

"Debe haber algo obvio que me falta aquí". - tal vez, y yo también ;-)
Comencemos con un pequeño ejemplo autónomo y veamos dónde difiere de tu código real.

class SOTest 
{ 
    private static String DecompressAndDecode(byte[] data) 
    { 
    GZipStream decompressor = new GZipStream(new MemoryStream(data), CompressionMode.Decompress); 
    StreamReader decompressed = new StreamReader(decompressor, Encoding.UTF8); 
    String result = decompressed.ReadToEnd(); 
    return result; 
    } 

    private static byte[] foo(string data) 
    { 
    MemoryStream dest = new MemoryStream(); 
    using (GZipStream compressor = new GZipStream(dest, CompressionMode.Compress)) 
    { 
     using (StreamWriter sw = new StreamWriter(compressor)) 
     { 
     sw.Write(data); 
     } 
    } 
    return dest.GetBuffer(); 
    } 


    static void Main() 
    { 
    System.Console.WriteLine(
     DecompressAndDecode(foo("Mary had a little lamb.")) 
    ); 
    return; 
    } 
} 

impresiones Mary had a little lamb.

+0

¡Gracias por tu ayuda! Tu ejemplo funciona La única diferencia en mi caso es que obtengo los datos de una base de datos SQL con SqlDataReader y el texto es bastante más largo y tiene algunos caracteres que no son ASCII. He encontrado que _en mi caso_ ReadToEnd devuelve el texto en la segunda llamada. – axk

+0

¿Tiene esto sólo sucede con los datos más largos o se puede reducir la cantidad de datos (pasó a DecompressAndDecode (byte []) para propósitos de depuración? – VolkerK

1

Crea tu propia función personalizada. Que va a tomar el camino como un parámetro:

static string read(string path) 
    { 
     StreamReader sr = new StreamReader(@path); 
     string txt = ""; 
     while (!sr.EndOfStream) { 
      txt += sr.ReadLine() + "\n"; 
     } 
     sr.Close(); 
     return txt; 
    } 

Entonces llaman en lugar de la llamada a ReadToEnd(). Lo probé y funcionó.

Cuestiones relacionadas