2010-12-16 9 views
13

Wiem, że to pytanie zostało wcześniej zadane na Stackoverflow, ale nie można znaleźć wyjaśnienia.StreamReader ReadToEnd() zwraca pusty ciąg przy pierwszej próbie

Kiedy próbuję odczytać ciąg ze skompresowanej tablicy bajtów, otrzymuję pusty ciąg przy pierwszej próbie, w drugim mam i otrzymuję ciąg.

przykładem Kod:

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

Wszystkie sugestie są mile widziane. - Victor Cassel

+0

Nie sądzę, że potrzebujesz czeku, wygląda na zbędny. – Nick

Odpowiedz

1

spróbuj dodać ms.Position = 0 przed string ret = sr.ReadToEnd();

+0

Próbowałem, i to nie pomaga, próbowałem również ms.Seek (0, SeekOrigin.Begin). –

1

The MSDN Page on the function wymienia następujące:

Jeśli obecna metoda zgłasza OutOfMemoryException, pozycja czytelnika w podstawowej obiektu Stream jest przesuwany przez liczbę znaków, które metoda była w stanie odczytać, ale znaki już wczytane do wewnętrznego bufora ReadLine są odrzucane. Jeśli manipulujesz położeniem strumienia bazowego po odczytaniu danych do bufora, pozycja strumienia bazowego może nie odpowiadać położeniu bufora wewnętrznego. Aby zresetować wewnętrzny bufor, wywołaj metodę DiscardBufferedData; jednak ta metoda spowalnia działanie i powinna być wywoływana tylko wtedy, gdy jest to absolutnie konieczne.

Może spróbować nazywając DiscardBufferedData() przed ReadToEnd() i zobaczyć, co robi (wiem, że nie są coraz wyjątek, ale to wszystko, co mogę myśleć ...)?

+0

Nie, wywołanie DiscarBufferedData() również nie pomogło. –

1

Mam nadzieję, że to pomoże.

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

Można zastąpić if(!(read > 0)) z if(read <= 0). Z jakiegoś powodu if(read <= 0) nie jest wyświetlany powyżej.

dla strumienia:

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

Gdzie jest gzBuffer pochodzących z? Czy napisałeś również kod, który tworzy skompresowane dane?

Być może dane w buforze są nieprawidłowe lub w jakiś sposób niekompletne lub może składać się z wielu strumieni deflacyjnych połączonych razem.

+0

Znalazłem błąd. Było tak, jak sugerował Michael w procedurze kompresji. Nie mogłem zadzwonić do Close() na GZipStream. compress.Write (raw, 0, raw.Length); compress.Close(); return ms.ToArray(); Stało się tak, że dane zdawały się być zapisywane w złym stanie, który wymagał dwóch wywołań funkcji ReadToEnd() w procedurze dekompresji później, aby wyodrębnić te same dane. Bardzo dziwne! –

3

Znalazłem błąd. Było tak, jak sugerował Michael w procedurze kompresji. Nie mogłem zadzwonić do Close() na 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(); 
     } 
    } 
} 

Co się stało, że dane zapisywane wydawało się w złym stanie, że wymaga dwóch połączeń do ReadToEnd() w procedurze dekompresji później wyodrębnić te same dane. Bardzo dziwne!

Powiązane problemy