2010-12-16 18 views
13

Sé que esta pregunta se ha formulado anteriormente en Stackoverflow, pero no ha podido encontrar una explicación.StreamReader ReadToEnd() devuelve una cadena vacía en el primer intento

Cuando trato de leer una cadena de una matriz de bytes comprimida obtengo una cadena vacía en el primer intento, en el segundo que éxito y obtengo la cadena.

ejemplo Código:

public static string Decompress(byte[] gzBuffer) 
{ 
    if (gzBuffer == null) 
     return null; 
    using (var ms = new MemoryStream(gzBuffer)) 
    { 
     using (var decompress = new GZipStream(ms, CompressionMode.Decompress)) 
     { 
      using (var sr = new StreamReader(decompress, Encoding.UTF8)) 
      { 
       string ret = sr.ReadToEnd(); 
       // this is the extra check that is needed !? 
       if (ret == "") 
        ret = sr.ReadToEnd(); 
       return ret; 
      } 
     } 
    } 
} 

son apreciados Todas las sugerencias. - Victor Cassel

+0

No creo que necesite el cheque, parece redundante. – Nick

Respuesta

1

intento de añadir ms.Position = 0 antes string ret = sr.ReadToEnd();

+0

Lo intenté y no ayuda, también probé ms.Seek (0, SeekOrigin.Begin). –

1

The MSDN Page on the function menciona lo siguiente:

Si el método actual arroja una OutOfMemoryException, la posición del lector en el objeto Stream subyacente es avanzado por el número de caracteres que el método pudo leer, pero los caracteres ya leídos en el búfer ReadLine interno se descartan. Si manipula la posición de la secuencia subyacente después de leer los datos en la memoria intermedia, la posición de la secuencia subyacente podría no coincidir con la posición de la memoria intermedia interna. Para restablecer el búfer interno, llame al método DiscardBufferedData; sin embargo, este método reduce el rendimiento y debe llamarse solo cuando sea absolutamente necesario.

Tal vez intente llamar DiscardBufferedData() antes de ReadToEnd() y ver lo que hace (sé que no está recibiendo la excepción, pero es todo lo que puedo pensar ...)?

+0

No, llamar a DiscarBufferedData() tampoco ayudó. –

1

Espero que esto ayude.

Para ByteArray:

static byte[] CompressToByte(string data) 
{ 
    MemoryStream outstream = new MemoryStream(); 
    GZipStream compressionStream = 
    new GZipStream(outstream, CompressionMode.Compress, true); 
    StreamWriter writer = new StreamWriter(compressionStream); 
    writer.Write(data); 
    writer.Close(); 
    return StreamToByte(outstream); 
} 

static string Decompress(byte[] data) 
{ 
    MemoryStream instream = new MemoryStream(data); 
    GZipStream compressionStream = 
    new GZipStream(instream, CompressionMode.Decompress); 
    StreamReader reader = new StreamReader(compressionStream); 
    string outtext = reader.ReadToEnd(); 
    reader.Close(); 
    return outtext; 
} 

public static byte[] StreamToByte(Stream stream) 
{ 
    stream.Position = 0; 
    byte[] buffer = new byte[128]; 
    using (MemoryStream ms = new MemoryStream()) 
    { 
     while (true) 
     { 
      int read = stream.Read(buffer, 0, buffer.Length); 
      if (!(read > 0)) 
       return ms.ToArray(); 
      ms.Write(buffer, 0, read); 
     } 
    } 
}

Puede reemplazar if(!(read > 0)) con if(read <= 0). Por alguna razón if(read <= 0) no se muestra en la parte superior.

Para Stream:

static Stream CompressToStream(string data) 
{ 
    MemoryStream outstream = new MemoryStream(); 
    GZipStream compressionStream = 
    new GZipStream(outstream, CompressionMode.Compress, true); 
    StreamWriter writer = new StreamWriter(compressionStream); 
    writer.Write(data); 
    writer.Close(); 
    return outstream; 
} 

static string Decompress(Stream data) 
{ 
    data.Position = 0; 
    GZipStream compressionStream = 
    new GZipStream(data, CompressionMode.Decompress); 
    StreamReader reader = new StreamReader(compressionStream); 
    string outtext = reader.ReadToEnd(); 
    reader.Close(); 
    return outtext; 
}
2

Dónde está gzBuffer viene? ¿También escribiste el código que está produciendo los datos comprimidos?

Quizás los datos del búfer que tiene no son válidos o de alguna manera incompletos, o tal vez consisten en múltiples flujos de deflaxión concatenados.

+0

Encontré el error. Fue como Michael sugirió en la rutina de compresión. Me perdí para llamar a Close() en el GZipStream. compress.Write (raw, 0, raw.Length); compress.Close(); return ms.ToArray(); Lo que sucedió fue que los datos parecían haberse guardado en un estado incorrecto que requirió dos llamadas a ReadToEnd() en la rutina de descompresión más adelante para extraer los mismos datos. ¡Muy raro! –

3

Encontré el error. Fue como Michael sugirió en la rutina de compresión. Me perdí para llamar a Close() en el GZipStream.

public static byte[] Compress(string text) 
{ 
    if (string.IsNullOrEmpty(text)) 
     return null; 

    byte[] raw = Encoding.UTF8.GetBytes(text); 
    using (var ms = new MemoryStream()) 
    { 
     using (var compress = new GZipStream (ms, CompressionMode.Compress)) 
     { 
      compress.Write(raw, 0, raw.Length); 
      compress.Close(); 

      return ms.ToArray(); 
     } 
    } 
} 

lo que ocurrió fue que los datos parecían ser salvo en mal estado que requiere dos llamadas a ReadToEnd() en la rutina de descompresión después de extraer los mismos datos. ¡Muy raro!

Cuestiones relacionadas