我即将失去我的怪异头脑。 我一直试图让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

===============>>#1 票数:2

必须先关闭(处置) System.IO.Compression.GZipStream才能使用基础流,因为

  1. 它以块为导向
  2. 它必须写入页脚,包括校验和(请参阅Wikipedia上的文件格式说明

===============>>#2 票数: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();
}

===============>>#3 票数:0 已采纳

正如其他人所说,您需要关闭GZipStream才能获得完整数据。 using语句将导致在块结尾处的流上调用Dispose方法,如果流尚未关闭,它将关闭流。 如果您放置zip.Close();上面的所有示例都将按预期工作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();
}

  ask by zoombini translate from so

未解决问题?本站智能推荐:

关注微信公众号