2009-10-22 52 views
2

我不知道任何人都可以对我发疯的问题提供一些线索:令人费解的.Net C#DeflateStream问题

我写一个压缩解压测试类。为了测试它,我将数据集序列化为内存流,对其进行压缩,然后解压缩并比较结果。

压缩很好,但未压缩就是它碰到泥土的地方。 这是解压缩功能:

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

随着尺寸65536的缓冲解压缩流总是返回一个字节小于它被压缩。

现在这让我想起了我正在与之对抗的第二个问题。对于某些缓冲区大小,即使仍有压缩数据要提取,uncompressStream.Read也会返回0。

对于这些情况,只需在do {}循环中deflateStream.Read(s)一次,然后返回一个等于buffersize的未压缩流,如果将缓冲区大小增加一个字节,则一切正常(除了丢失的字节)。

输出为65536的缓冲区大小(原始的未压缩数据是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] 

189544(一些神奇的数字,其中的代码罐)

bytesRead: [189544]  outStream.Length [189544] 
bytesRead: [0]   outStream.Length [189544] 
total bytes read [189544] 
Unompressed stream size 189544 

还要注意缓冲区大小的第三读65536 ex:bytesRead:[58472]显然,​​这也应该是65536,因为缓冲区中仍有数据?

任何想法将大大赞赏。

TIA

  • 雅科
+0

你怎么能说如果你不能解压缩数据压缩就好了? – 2009-10-22 14:35:56

+0

Hi Lasse, 我写了另一个实现,其中相同数据集的压缩大小等于流后压缩的大小。 - 希望有道理 – twiga 2009-10-22 14:43:53

回答

4

您应该始终在压缩流上调用Close()。请注意Flush()是不够。我怀疑因为这个,泄气流缺少数据。

+0

首先,关闭没有工作,因为它关闭了基础流以及。但在使用true选项创建deflatestream后调用.Close()以离开Open,我可以关闭它,并将基础流传回给调用者! tyvm! – twiga 2009-10-22 15:19:59

+0

DeflateStream是一个流,这意味着它是IDisposable。你需要一个使用条款。尽管Close()可能已经足够,但您通过不调用Dispose()或将它放在using子句中来违反了使用模型。 – Cheeso 2009-10-23 05:54:07

3

我的精神力量告诉我,你在做实际上有一个工作减压的实施,但已经忘记了之前刷新压缩流。

+0

a DeflateStream.Close()纠正它tyvm – twiga 2009-10-22 15:21:03

0

好吧,我找不到你的问题,但按照我前一段时间写的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);