Quindi ecco uno strano. Ho questo metodo per prendere una stringa sgonfio codifica Base64 e restituire i dati originari:DeflateStream non decomprime i dati (la prima volta)
public static string Base64Decompress(string base64data)
{
byte[] b = Convert.FromBase64String(base64data);
using (var orig = new MemoryStream(b))
{
using (var inflate = new MemoryStream())
{
using (var ds = new DeflateStream(orig, CompressionMode.Decompress))
{
ds.CopyTo(inflate);
return Encoding.ASCII.GetString(inflate.ToArray());
}
}
}
}
Questo restituisce una stringa vuota se non aggiungo una seconda chiamata a ds.CopyTo(inflate)
. (WTF?)
...
using (var ds = new DeflateStream(orig, CompressionMode.Decompress))
{
ds.CopyTo(inflate);
ds.CopyTo(inflate);
return Encoding.ASCII.GetString(inflate.ToArray());
}
...
(Flush
/Close
/Dispose
su ds
non hanno effetto.)
Perché le DeflateStream
copia 0 byte alla prima chiamata? Ho anche provato a fare il ciclo con Read()
, ma restituisce anche zero alla prima chiamata, quindi funziona sul secondo.
Aggiornamento: ecco il metodo che sto usando per comprimere i dati.
public static string Base64Compress(string data, Encoding enc)
{
using (var ms = new MemoryStream())
{
using (var ds = new DeflateStream(ms, CompressionMode.Compress))
{
byte[] b = enc.GetBytes(data);
ds.Write(b, 0, b.Length);
ds.Flush();
return Convert.ToBase64String(ms.ToArray());
}
}
}
Questo è molto interessante. Cosa succede quando sostituisci il primo dei due 'ds.CopyTo()' con un 'ds.Read (...)'? Il primo 'CopyTo()' si attiva leggendo sul piè di pagina del flusso. 'Leggi()' dovrebbe fare lo stesso. Mi stavo solo chiedendo. –
Sei sicuro che sia deflate e non compresso con gzip? E sei sicuro che non ci siano altre cose di fronte ai dati deflate (o gzip?)? – nos
@Pieter: un '.Read()' ha lo stesso effetto - restituisce '0', ma fa sì che la prossima chiamata a' CopyTo() 'funzioni. – josh3736