GZipStream 在写入 FileStream 时有效,但不能写入 MemoryStream

本文关键字:但不能 MemoryStream 有效 FileStream GZipStream | 更新日期: 2023-09-27 18:30:16

如果压缩一些json文本,并使用FileStream将其写入文件,我会得到预期的结果。但是,我不想写入磁盘。我只想存储压缩数据的流。

压缩到FileStream

string json = Resource1.json;
using (MemoryStream input = new MemoryStream(Encoding.UTF8.GetBytes(json)))
using (FileStream output = File.Create(@"C:'Users'roarker'Desktop'output.json.gz"))
{
    using (GZipStream compression = new GZipStream(output, CompressionMode.Compress))
    {
        input.CopyTo(compression);
    }
}

以上作品。下面,输出内存流的长度为 10,并导致空.gz文件。

string json = Resource1.json;
using (MemoryStream input = new MemoryStream(Encoding.UTF8.GetBytes(json)))
using (MemoryStream output = new MemoryStream())
{
    using (GZipStream compression = new GZipStream(output, CompressionMode.Compress))
    {
        input.CopyTo(compression);
        byte[] bytes = output.ToArray();
    }
}

编辑:output.ToArray()移到内部using条款之外似乎有效。但是,对于大多数使用情况,这会关闭输出流。即:

        using (MemoryStream input = new MemoryStream(Encoding.UTF8.GetBytes(json)))
        using (MemoryStream output = new MemoryStream())
        {
            using (GZipStream compression = new GZipStream(output, CompressionMode.Compress))
            {
                input.CopyTo(compression);
            }
            WriteToFile(output);
        }

哪里:

    public static void WriteToFile(Stream stream)
    {
        using (FileStream output = File.Create(@"C:'Users'roarker'Desktop'output.json.gz"))
        {
            stream.CopyTo(output);
        }
    }

这将在流式传输中失败。复制到,因为流已关闭。我知道我可以用output.ToArray()字节制作一个新的Stream,但为什么这是必要的?为什么ToArray()在流关闭时起作用?

最终编辑:

只需要将GZipStream的构造器与leaveOpen参数一起使用即可。

GZipStream 在写入 FileStream 时有效,但不能写入 MemoryStream

您在关闭GZipStream之前正在呼叫ToArray()...这意味着它没有机会刷新其缓冲区的最后位。这是压缩加密流的常见问题,其中关闭流需要写入一些最终数据片段。(例如,即使明确调用Flush()也无济于事。

只需移动ToArray调用:

using (MemoryStream input = new MemoryStream(Encoding.UTF8.GetBytes(json)))
using (MemoryStream output = new MemoryStream())
{
    using (GZipStream compression = new GZipStream(output, CompressionMode.Compress))
    {
        input.CopyTo(compression);
    }
    byte[] bytes = output.ToArray();
    // Use bytes
}

(请注意,当您调用ToArray时,流将被释放,但这没关系。

相关文章: