2010-04-03 24 views
8

Ho un metodoStreamReader.ReadToEnd() restituendo una stringa vuota

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; 
} 

ho un testo GZipped come input e il risultato dovrebbe essere una rappresentazione stringa di testo. Il problema è che il metodo restituisce una stringa vuota. Quello che mi è sconcertante è che quando faccio un passo Trough il metodo in modalità debug e raggiungere l'istruzione return la variabile risultato è una stringa vuota, ma se creo un orologio per l'espressione decompressed.ReadToEnd() mi restituisce il testo. Quello che mi aspetterei a questo punto è la variabile result per contenere il testo e l'espressione decompressed.ReadToEnd() che valuta una stringa vuota. (Rivalutare l'espressione decompressed.ReadToEnd() restituisce una stringa vuota come previsto).

@EDIT: Ho scoperto che nel mio caso ReadToEnd() restituisce il testo sulla seconda chiamata ritorno stringhe vuote in prima convocazione e, dopo la seconda chiamata.

Ci deve essere qualcosa di ovvio che mi manca qui.

+0

è la codifica in realtà UTF8? –

+0

Sì, è UTF8. – axk

risposta

21

Credo che il problema è la posizione del puntatore nel vapore. Ogni volta che si esegue lo ReadToEnd, il puntatore è impostato sulla fine, motivo per cui è possibile guardarlo per la prima volta.

eseguire il seguente codice prima ReadToEnd per impostare il puntatore all'inizio. someStream.Seek(0, SeekOrigin.Begin)

+0

Questo ha risolto il problema per me – Aaronontheweb

+0

Non esiste alcuna funzione membro Cerca per streamReader. – stackptr

+0

@stackptr you è necessario utilizzarlo nello stream che si alimenta con streamReader –

1

"Ci deve essere qualcosa di ovvio che mi manca qui." - forse, e così sono io ;-)
Cominciamo con un piccolo esempio autonomo e vedere dove si differenzia dal codice vero e proprio.

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; 
    } 
} 

stampe Mary had a little lamb.

+0

Grazie per il tuo aiuto! Il tuo esempio funziona. L'unica differenza nel mio caso sto ricevendo i dati da un database SQL con un SqlDataReader e il testo è un po 'più lungo e ha alcuni caratteri non ascii. Ho trovato che _in my case_ ReadToEnd restituisce il testo sulla seconda chiamata. – axk

+0

Questo si verifica solo con dati più lunghi o è possibile ridurre la quantità di dati (passati a DecompressAndDecode (byte []) a scopo di debug? – VolkerK

1

Crea la tua funzione personalizzata. Ci vorrà il percorso come parametro:

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

Poi lo chiamano invece della chiamata a ReadToEnd(). L'ho provato e ha funzionato.

Problemi correlati