1

以下是我编写的一个简单的压缩方法DeflateStream

public static int Compress(
    byte[] inputData, 
    int inputStartIndex, 
    int inputLength, 
    byte[] outputData, 
    int outputStartIndex, 
    int outputLength)
{
    if (inputData == null)
        throw new ArgumentNullException("inputData must be non-null");

    MemoryStream memStream = new MemoryStream(outputData, outputStartIndex, outputLength);

    using (DeflateStream dstream = new DeflateStream(memStream, CompressionLevel.Optimal))
    {
        dstream.Write(inputData, inputStartIndex, inputLength);
        return (int)(memStream.Position - outputStartIndex);
    }
}

这个方法的特别之处在于我没有使用MemoryStream. 这是因为它是一个高吞吐量的服务器。数组outputData是从 租来的ArrayPool,用来保存压缩后的字节,这样我用完后可以把它还给ArrayPool.

压缩发生正确,压缩数据正确放入outputData,但memStream.Position为零,所以我无法找出已写入MemoryStream.

只有一部分outputData被压缩数据占用。如何找出压缩数据的长度?

4

1 回答 1

1

MemoryStream.Position为 0,因为在您读取时尚未实际写入数据Position。相反,告诉DeflateStream让底层流 ( MemoryStream) 打开,然后处置DeflateStream。在这一点上,您可以确定它已完成编写所需的任何内容。现在您可以阅读MemoryStream.Position以检查写入了多少字节:

public static int Compress(
    byte[] inputData, 
    int inputStartIndex, 
    int inputLength, 
    byte[] outputData, 
    int outputStartIndex, 
    int outputLength)
{
    if (inputData == null)
        throw new ArgumentNullException("inputData must be non-null");

    using (var memStream = new MemoryStream(outputData, outputStartIndex, outputLength)) {

        // leave open
        using (DeflateStream dstream = new DeflateStream(memStream, CompressionLevel.Optimal, leaveOpen: true)) {
            dstream.Write(inputData, inputStartIndex, inputLength);
        }

        return (int) memStream.Position; // now it's not 0
    }
}

您也不需要 substract outputStartIndex,因为Position它已经相对于您传递给构造函数的索引。

于 2021-10-10T08:57:44.457 回答