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

Dav*_*ave 3 .net c# gzipstream

如果压缩一些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);
    }
}
Run Code Online (Sandbox Code Playgroud)

以上作品.下面,输出内存流的长度为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();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑: 移出output.ToArray()内部using条款似乎工作.但是,这会关闭大多数用法的输出流.IE:

        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);
        }
Run Code Online (Sandbox Code Playgroud)

其中:

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

这将在stream.CopyTo失败,因为流已关闭.我知道我可以Stream从字节中创建一个新的output.ToArray(),但为什么这是必要的?为什么ToArray()在关闭流时工作?

最终编辑:

只需要使用GZipStreamleaveOpen参数的构造函数.

Jon*_*eet 12

ToArray()在关闭之前你正在调用GZipStream...这意味着它没有机会刷新缓冲区的最后一位.这是压缩加密流的常见问题,关闭流需要编写一些最终的数据.(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
}
Run Code Online (Sandbox Code Playgroud)

(注意,当你打电话时ToArray,会丢弃流,但没关系.)

  • 啊,我也许可以使用 LeaveOpen 构造函数参数来完成我想要的操作。 (2认同)