2010-12-16 14 views
13

Bu sorunun Stackoverflow üzerinde daha önce sorulmuş olduğunu biliyorum, ancak bir açıklama bulamadım.StreamReader ReadToEnd() ilk denemede boş dizgi döndürür

Sıkıştırılmış bir bayt dizisinden bir dize okumaya çalıştığımda, ilk denemede boş bir dize alıyorum, ikincisinde, ipliğim ve dizeyi aldım.

Kod örnek: Tüm önerileri takdir edilmektedir

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

. - Victor Cassel

+0

Denetime ihtiyacın olduğunu düşünmüyorum, gereksiz görünüyor. – Nick

cevap

1

deneyin

+0

Bunu denedim ve yardımcı olmadı, ayrıca ms.Seek (0, SeekOrigin.Begin) denedim. –

1

The MSDN Page on the function aşağıdaki söz ms.Position = 0string ret = sr.ReadToEnd(); önce ilave: Mevcut yöntem OutOfMemoryException atar

, altta yatan Akış nesnesi okuyucunun pozisyonu sayısına göre ilerletilir yöntemin okuyabildiği karakterler, ancak dahili ReadLine arabelleğine zaten yazılan karakterler atılır. Veriyi arabellekte okuduktan sonra temel akışın konumunu değiştirirseniz, temel akışın konumu dahili arabelleğin konumuyla eşleşmeyebilir. Dahili arabelleği sıfırlamak için DiscardBufferedData yöntemini çağırın; Ancak, bu yöntem performansı yavaşlatır ve yalnızca kesinlikle gerekli olduğunda çağrılmalıdır.

Belki ReadToEnd() önce DiscardBufferedData() çağırarak denemek ve Ne yaptığını görmek (Ben istisna almıyorsanız biliyorum, ama bu ben ... aklınıza gelebilecek hepsi)?

+0

Hayır, DiscarBufferedData() çağrısı da yardımcı olmadı. –

1

Umarım bu yardımcı olur. ByteArray için

:

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

Sen if(read <= 0) ile if(!(read > 0)) yerini alabilir. Herhangi bir nedenle if(read <= 0), yukarıda belirtilen şekilde gösterilmemiştir. Akış için

:

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

gzBuffer geliyor? Sıkıştırılmış verileri üreten kodu da yazdınız mı?

Belki de, sahip olduğunuz arabellek verileri geçersizdir veya bir şekilde eksiktir ya da belki bir araya getirilmiş birden fazla deflate akımından oluşur.

+0

Hata buldum. Michael'ın sıkıştırma rutininde önerdiği gibiydi. GZipStream üzerinde Close() aramayı özledim. compress.Write (işlenmemiş, 0, işlenmemiş uzunluk); compress.Close(); dönüş ms.ToArray(); Ne oldu? Veriler, aynı verileri ayıklamak için daha sonra açma işlemi sırasında ReadToEnd() öğesine yapılan iki çağrıya ihtiyaç duyan kötü bir durumda kaydedilmiş gibi görünüyordu. Çok tuhaf! –

3

Hata buldum. Michael'ın sıkıştırma rutininde önerdiği gibiydi. GZipStream üzerinde Close() aramayı özledim.

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

ne oldu veriler aynı verileri ayıklamak için sonradan dekompresyon rutininde ReadToEnd() için iki çağrı gerekli kötü durumda kurtarılmayı gibiydi olmasıydı. Çok tuhaf!

İlgili konular