如何获取DeflateStream向预分配MemoryStream写入的压缩数据长度?
问题根因
你当前的写法有两个核心问题:
- 返回逻辑写在了
DeflateStream的using代码块内部,此时DeflateStream还未执行销毁逻辑,它内部缓存的压缩数据还没有完全刷入底层的MemoryStream,同时压缩流所需的收尾数据(块结束标识、校验和等)也未写入,此时读取memStream.Position自然得不到正确值。 DeflateStream属于缓冲流,默认不会每写入一点数据就立刻同步到底层流,只有缓冲满、显式调用Flush或者对象销毁时才会执行批量写入操作。
解决方案
只需要把读取长度的逻辑移到DeflateStream的using块外部即可,修改后的代码如下:
public static int Compress( byte[] inputData, int inputStartIndex, int inputLength, byte[] outputData, int outputStartIndex, int outputLength) { if (inputData == null) throw new ArgumentNullException(nameof(inputData), "inputData must be non-null"); MemoryStream memStream = new MemoryStream(outputData, outputStartIndex, outputLength, true); using (DeflateStream dstream = new DeflateStream(memStream, CompressionLevel.Optimal)) { dstream.Write(inputData, inputStartIndex, inputLength); } // 此时DeflateStream已销毁,所有压缩数据已完全写入底层数组 return (int)(memStream.Position - outputStartIndex); }
补充说明
MemoryStream即使被DeflateStream连带关闭,它的Position、Length属性依然可以正常读取,不会抛出异常,不影响长度计算。- 你使用
ArrayPool租赁数组的写法完全适配该修改,不会产生额外的数组分配,符合高吞吐场景的性能要求。
内容的提问来源于stack exchange,提问作者user788454
相关产品推荐
相关产品推荐

