我即将失去我的头脑。我一直试图让GzipStream在过去一小时内压缩字符串,但无论出于何种原因,它都拒绝将整个字节数组写入内存流。起初我认为它与using语句有关,但即使在删除它们之后它似乎也没有什么区别。
初始配置:
var str = "Here is a relatively simple string to compress";
byte[] compressedBytes;
string returnedData;
var bytes = Encoding.UTF8.GetBytes(str);
正常工作(写入64个长度字节数组):
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
msi.CopyTo(gs);
}
compressedBytes = mso.ToArray();
}
失败(写入10个长度字节数组):
using(var mso = new MemoryStream())
using(var msi = new MemoryStream(bytes))
using(var zip = new GZipStream(mso, CompressionMode.Compress))
{
msi.CopyTo(zip);
compressedBytes = mso.ToArray();
}
也失败(写入10个长度字节数组):
var mso = new MemoryStream();
var msi = new MemoryStream(bytes);
var zip = new GZipStream(mso, CompressionMode.Compress);
msi.CopyTo(zip);
compressedBytes = mso.ToArray();
有人可以解释为什么第一个有效,但在另外两个我得到这些不完整的数组?是什么东西从我身下消失了?就此而言,我有办法避免使用两个内存流吗?
谢谢, Zoombini
答案 0 :(得分:2)
System.IO.Compression.GZipStream
必须先关闭(处置)才能使用基础流,因为
答案 1 :(得分:1)
您在GZipStream
关闭之前尝试获取压缩数据。正如您所见,这并不会返回完整数据。第一个有效的原因是因为您在 compressedBytes = mso.ToArray();
被处理后正在调用GZipStream
。所以,未经测试但在理论上,您应该能够稍微修改您的第二个代码,以使其工作。
using(var mso = new MemoryStream())
{
using(var msi = new MemoryStream(bytes))
using(var zip = new GZipStream(mso, CompressionMode.Compress))
{
msi.CopyTo(zip);
}
compressedBytes = mso.ToArray();
}
答案 2 :(得分:0)
正如其他人所说,您需要关闭GZipStream
才能获得完整数据。 using
语句将导致在块末尾的流上调用Dispose
方法,如果流尚未关闭,将关闭流。如果您在zip.Close();
之后放置msi.CopyTo(zip);
,则上述所有示例都将按预期工作。
如果以这种方式编写,可以删除其中一个MemoryStream:
using (MemoryStream mso = new MemoryStream())
{
using (GZipStream zip = new GZipStream(mso, CompressionMode.Compress))
{
zip.Write(bytes, 0, bytes.Length);
}
compressedBytes = mso.ToArray();
}