无损压缩少量数据时如何达到最小尺寸?

发布于 2024-10-20 06:15:22 字数 2168 浏览 1 评论 0原文

  1. 我不明白“为什么 gzip/deflate 压缩小文件会导致许多尾随零?”的答案 (为什么 gzip/deflate压缩小文件会导致许多尾随零?

  2. 如何在 .NET 环境中将少量数据压缩到 ½-2 Kbyte 到最小大小? (运行时间对我来说不是问题。我可以用速度换取大小吗?我应该使用第 3 方产品吗? 开发人员许可费用可以,但运行时许可费用不行。)

  3. 有关如何改进以下代码的任何建议:
    (a) 更高的压缩比?
    (b) 更正确地使用流?

这是需要改进的 C# 代码:

private static byte[] SerializeAndCompress(MyClass myObject)  
{
   using (var inStream = new System.IO.MemoryStream())
   {

     Serializer.Serialize< MyClass >(inStream, myObject); // PROTO-buffer  serialization. (Code not included here.)
     byte[] gZipBytearray = GZipCompress(inStream);
     return gZipBytearray;
   }
}

private static Byte[] GZipCompress(MemoryStream inStream)
{
   inStream.Position = 0;

   byte[] byteArray;
   {
      using (MemoryStream outStream = new MemoryStream())
      {
         bool LeaveOutStreamOpen = true;
         using (GZipStream compressStream = new GZipStream(outStream, 
            CompressionMode.Compress, LeaveOutStreamOpen))
         {
         // Copy the input stream into the compression stream.
         // inStream.CopyTo(Compress); TODO: "Uncomment" this line and remove the next one after upgrade to .NET 4 or later.
            CopyFromStreamToStream(inStream, compressStream);
     }
     byteArray = CreateByteArrayFromStream(outStream); // outStream is complete first after compressStream have been closed.
      }
   }
   return byteArray;
}

private static void CopyFromStreamToStream(Stream sourceStream, Stream destinationStream)
{
   byte[] buffer = new byte[4096];
   int numRead;
   while ((numRead = sourceStream.Read(buffer, 0, buffer.Length)) != 0)
   {
     destinationStream.Write(buffer, 0, numRead);
   }
}

private static byte[] CreateByteArrayFromStream(MemoryStream outStream)
{
   byte[] byteArray = new byte[outStream.Length];
   outStream.Position = 0;
   outStream.Read(byteArray, 0, (int)outStream.Length);
   return byteArray;
}
  1. I don’t understand the answer to ”Why does gzip/deflate compressing a small file result in many trailing zeroes?
    (Why does gzip/deflate compressing a small file result in many trailing zeroes?)

  2. How would you go about compressing small amount of data ½-2 Kbyte to minimum size in a .NET-environment?
    (Runtime is not an issue for me. Can I trade speed for size? Should I use 3rd party products?
    Developer license fees are OK, but runtime license not.)

  3. Any suggestions about how I can improve the code below for:
    (a) Higher compression ratio?
    (b) More proper use of streams?

Here is the C#-code that needs to be improved:

private static byte[] SerializeAndCompress(MyClass myObject)  
{
   using (var inStream = new System.IO.MemoryStream())
   {

     Serializer.Serialize< MyClass >(inStream, myObject); // PROTO-buffer  serialization. (Code not included here.)
     byte[] gZipBytearray = GZipCompress(inStream);
     return gZipBytearray;
   }
}

private static Byte[] GZipCompress(MemoryStream inStream)
{
   inStream.Position = 0;

   byte[] byteArray;
   {
      using (MemoryStream outStream = new MemoryStream())
      {
         bool LeaveOutStreamOpen = true;
         using (GZipStream compressStream = new GZipStream(outStream, 
            CompressionMode.Compress, LeaveOutStreamOpen))
         {
         // Copy the input stream into the compression stream.
         // inStream.CopyTo(Compress); TODO: "Uncomment" this line and remove the next one after upgrade to .NET 4 or later.
            CopyFromStreamToStream(inStream, compressStream);
     }
     byteArray = CreateByteArrayFromStream(outStream); // outStream is complete first after compressStream have been closed.
      }
   }
   return byteArray;
}

private static void CopyFromStreamToStream(Stream sourceStream, Stream destinationStream)
{
   byte[] buffer = new byte[4096];
   int numRead;
   while ((numRead = sourceStream.Read(buffer, 0, buffer.Length)) != 0)
   {
     destinationStream.Write(buffer, 0, numRead);
   }
}

private static byte[] CreateByteArrayFromStream(MemoryStream outStream)
{
   byte[] byteArray = new byte[outStream.Length];
   outStream.Position = 0;
   outStream.Read(byteArray, 0, (int)outStream.Length);
   return byteArray;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文