【问题标题】:Is there any workaround for .Net 6 System.IO.Compression issue. DeflateStream.Read method works incorrect in .Net 6, but works fine in older versions.Net 6 System.IO.Compression 问题是否有任何解决方法。 DeflateStream.Read 方法在 .Net 6 中工作不正确,但在旧版本中工作正常
【发布时间】:2022-07-12 23:51:14
【问题描述】:

这是来自实际项目的代码,用于问题,所以一些数据是硬编码的:

   static void Main(string[] args)
    {
        Console.WriteLine("Starting. " + Environment.Version);
        using (var stream = new FileStream(@"stream_test.txt", FileMode.Open))
        {
            stream.Position = 0;

            // .NET implements Deflate (RFC 1951) but not zlib (RFC 1950),
            // so we have to skip the first two bytes.
            stream.ReadByte();
            stream.ReadByte();

            var zipStream = new DeflateStream(stream, CompressionMode.Decompress, true);

            // Hardcoded length from real project. In the previous .Net versions this is size of final result
            long bytesToRead = (long)262 * 350;

            var buffer = new byte[bytesToRead];
            int bytesWereRead = zipStream.Read(buffer, 0, (int)bytesToRead);

            if (bytesWereRead != bytesToRead)
            {
                throw new Exception("ZIP stream was not fully decompressed.");
            }

            Console.WriteLine("Ok");
            Console.ReadKey();
        }
    }

解压缩问题不会出现在每个流上,因此可以在 GitHub 上找到带有项目代码的输入文件。 https://github.com/dimsa/Net6DeflateStreamIssue/tree/main/DeflateStreamTest

这段代码很好在:

  • .NET Framework(在 2.0、3.5、4 上测试过)
  • .NET 标准 2.1 和
  • .NET 5

.NET 6 失败。 Net 6中解压后的数据长度不正确。

是否有任何解决方法,或者应该使用其他压缩库?

【问题讨论】:

  • 您是否向 dotnet 团队报告了此错误?看来您已经对此问题进行了相当多的调查,但是这可能是请求修复的错误地方。
  • @PMF 看起来 MS 知道这个问题。答案有指向官方评论的链接。谢谢。

标签: c# compression .net-6.0


【解决方案1】:

DeflateStream 在 .NET 6 中的运行方式发生了重大变化。您可以阅读有关它的更多信息以及建议的操作in this Microsoft documentation。

基本上,您需要包装.Read 操作并检查读取的长度与预期长度,因为该操作现在可能会在读取完整长度之前返回。您的代码可能如下所示(基于文档中的示例):

int totalRead = 0;
var buffer = new byte[bytesToRead];
while (totalRead < buffer.Length)
{
    int bytesRead = zipStream.Read(buffer.Slice(totalRead));
    if (bytesRead == 0) break;
    totalRead += bytesRead;
}

【讨论】:

    【解决方案2】:

    另一种解决方法。只是方式不同。

                    var totalRead = 0;
                    var byteRead = 0;
                    while (totalRead < dataLength)
                    {
                        byteRead = gZipStream.Read(buffer, totalRead, dataLength - totalRead);
                        if (byteRead == 0) break;
                        totalRead += byteRead;
                    }
    

    【讨论】:

      猜你喜欢
      • 2022-08-09
      • 1970-01-01
      • 2018-10-29
      • 2019-03-11
      • 1970-01-01
      • 1970-01-01
      • 2019-04-07
      • 1970-01-01
      • 2020-03-09
      相关资源
      最近更新 更多