Problema sconcertante .Net C # DeflateStream
-
05-07-2019 - |
Domanda
Mi chiedo se qualcuno possa far luce su un problema che mi sta facendo impazzire:
Sto scrivendo una classe di test di decompressione compressiva. Per provarlo, sto serializzando un set di dati in un flusso di memoria, lo comprime, lo decomprimo e confronto i risultati.
La compressione va bene, ma la compressione è dove colpisce la terra. Questa è la funzione di decompressione:
public static Stream GetUncompressedStreamCopy(Stream inStream)
{
Stream outStream = new MemoryStream();
inStream.Position = 0;
DeflateStream uncompressStream = new DeflateStream(inStream,
CompressionMode.Decompress, true);
byte[] buffer = new byte[65536];
int totalread = 0;
int bytesread = 0;
do {
bytesread = uncompressStream.Read(buffer, 0, buffer.Length);
totalread += bytesread;
outStream.Write(buffer, 0, bytesread);
Console.WriteLine("bytesRead: [{0}]\t outStream.Length [{1}]",
bytesread, outStream.Length);
} while (bytesread > 0);
Console.WriteLine("total bytes read [{0}]", totalread);
outStream.Flush();
return outStream;
}
Con un buffer di dimensioni 65536, il flusso decompresso restituisce sempre un byte in meno rispetto a quello non compresso.
Ora questo mi porta al secondo numero con cui sto combattendo. Con alcune dimensioni del buffer, uncompressStream.Read restituisce 0 anche se ci sono ancora dati compressi da estrarre.
In questi casi, deflateStream.Read (s) solo una volta nel ciclo do {} e quindi restituisce un flusso non compresso uguale a dimensione buffer, se si aumenta la dimensione buffer di un singolo byte tutto va bene (tranne il byte mancante) .
Output per buffersize di 65536: (i dati non compressi originali sono 207833)
bytesRead: [65536] outStream.Length [65536]
bytesRead: [65536] outStream.Length [131072]
bytesRead: [58472] outStream.Length [189544]
bytesRead: [18288] outStream.Length [207832]
bytesRead: [0] outStream.Length [207832]
total bytes read [207832]
buffersize del 189544 (alcuni numeri magici in cui il serbatoio di codice)
bytesRead: [189544] outStream.Length [189544]
bytesRead: [0] outStream.Length [189544]
total bytes read [189544]
Unompressed stream size 189544
Nota anche la terza lettura di buffersize 65536 ex: bytesLeggi: [58472] Chiaramente questo dovrebbe essere anche 65536 poiché ci sono ancora dei dati sul buffer?
Qualsiasi idea sarà molto apprezzata.
tia
- Jaco
Soluzione
Dovresti sempre chiamare Close () sui flussi di compressione. Tieni presente che Flush () non è non sufficiente . Ho il sospetto che a causa di ciò il flusso di deflazione sia privo di dati.
Altri suggerimenti
I miei poteri psichici mi dicono che in realtà hai un'implementazione decompressiva funzionante, ma hai dimenticato di svuotare il flusso di compressione prima.
Beh, non sono riuscito a individuare il tuo problema, ma segui un po 'di codice che ho scritto qualche tempo fa per ICSharpCode .SharpZipLib ;
byte[] compressedData;
using(MemoryStream ms = new MemoryStream())
{
Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION, true);
Stream s = new DeflaterOutputStream(ms, deflater);
s.Write(sendData, 0, sendData.Length);
s.Close();
compressedData = (byte[])ms.ToArray();
}
// ...
MemoryStream inflated = new MemoryStream();
using (Stream inflater = new InflaterInputStream(
inputStream, new Inflater(true)))
{
int count = 0;
byte[] deflated = new byte[4096];
while ((count = inflater.Read(deflated, 0, deflated.Length)) != 0)
{
inflated.Write(deflated, 0, count);
}
inflated.Seek(0, SeekOrigin.Begin);
}
byte[] content = new byte[inflated.Length];
inflated.Read(content, 0, content.Length);