如果压缩一些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
子句之外似乎有效。但是,这会关闭大多数用法的输出流。 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);
}
其中:
public static void WriteToFile(Stream stream)
{
using (FileStream output = File.Create(@"C:\Users\roarker\Desktop\output.json.gz"))
{
stream.CopyTo(output);
}
}
这将在stream.CopyTo失败,因为该流已关闭。我知道我可以从Stream
的字节创建一个新的output.ToArray()
,但为什么这是必要的?为什么ToArray()
在流关闭时有效?
最终修改:
只需使用带有GZipStream
参数的leaveOpen
的构造函数。
答案 0 :(得分:10)
在您关闭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
}
(请注意,当您拨打ToArray
时,系统会处理该流,但这没关系。)