Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将gZipStream与一个或两个内存流一起使用会产生很大的不同_C#_Compression_Memorystream_Gzipstream_Binaryformatter - Fatal编程技术网

C# 将gZipStream与一个或两个内存流一起使用会产生很大的不同

C# 将gZipStream与一个或两个内存流一起使用会产生很大的不同,c#,compression,memorystream,gzipstream,binaryformatter,C#,Compression,Memorystream,Gzipstream,Binaryformatter,我肯定错过了一些非常明显的东西,但谁能解释为什么在第二种情况下有更好的压缩率 情况1:压缩非常低,有时甚至会增大尺寸 using (var memoryStream = new System.IO.MemoryStream()) using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress)) { new BinaryFormatter().Serialize(gZipStream, obj);

我肯定错过了一些非常明显的东西,但谁能解释为什么在第二种情况下有更好的压缩率

情况1:压缩非常低,有时甚至会增大尺寸

using (var memoryStream = new System.IO.MemoryStream())
using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress))
{
  new BinaryFormatter().Serialize(gZipStream, obj);
  gZipStream.Close();
  return memoryStream.ToArray();
}
案例2:更好的压缩,我没有得到一个大小的增长

using (MemoryStream msCompressed = new MemoryStream())
using (GZipStream gZipStream = new GZipStream(msCompressed, CompressionMode.Compress))
using (MemoryStream msDecompressed = new MemoryStream())
{
  new BinaryFormatter().Serialize(msDecompressed, obj);
  byte[] byteArray = msDecompressed.ToArray();

  gZipStream.Write(byteArray, 0, byteArray.Length);
  gZipStream.Close();
  return msCompressed.ToArray();
}
我已经完成了镜像解压缩,在这两种情况下,我都可以将其反序列化到源对象中,而不会出现任何问题

以下是一些统计数据:

联合国资本规模:58062085B,公司1:46828139B,0.81%

UncSize:58062085B,Comp2:31326029B,0.54%

联合国资本规模:7624735B,公司1:7743947B,1.02%

联合国资本规模:7624735B,公司2:5337522B,0.70%

联合国资本规模:1237628B,公司1:1265406B,1.02%

联合国资本规模:1237628B,公司2:921695B,0.74%


你不能说你正在使用哪个版本的.NET。在4.0之前的版本中,
GZipStream
以每次写入为基础压缩数据。也就是说,它压缩发送给它的缓冲区。在第一个示例中,
Serialize
方法可能会将非常小的缓冲区写入流(一次一个字段)。在第二个示例中,
Serialize
将整个对象序列化为内存流,然后将内存流的缓冲区写入
GZipStream
GZipStream
如果有更大的缓冲区(64K接近最佳值)可供使用,则性能会更好

在.NET4.0中可能仍然是这样。我不记得我是否测试过它

我过去处理这件事的方式是:

这样,压缩器就可以使用64K的缓冲区


在.NET4.0之前,为
GZipStream
提供大于64K的缓冲区没有任何好处。我看到一些信息表明.NET4.0中的压缩器可以使用更大的缓冲区更好地进行压缩。不过,我自己还没有测试过。

谢谢。这正是我想要的。我使用的是.NET4.0,但情况仍然如此。正如你所说的,64k是最好的。较小的缓冲区会导致较弱的压缩。为了更好地管理内存,我已经将代码改为使用BufferStream,而不是两个内存流。谢谢
using (var mstream = new MemoryStream())
{
    using (var bstream = new BufferedStream(new GZipStream(mstream, CompressionMode.Compress), 65536))
    {
        new BinaryFormatter().Serialize(btream, obj);
    }
    return mstream.ToArray();
}