【问题标题】:Decompressing using GZipStream returns only the first line使用 GZipStream 解压只返回第一行
【发布时间】:2012-06-26 09:26:14
【问题描述】:

我一直在研究解析第 3 方 fms 日志的函数。日志采用 Gzip 格式,因此我使用了适用于我们使用的任何其他 Gzip 文件的解压缩功能。

解压这些文件时,我只得到压缩文件的第一行,也不例外,只是没有找到其余的字节,好像第一行有一个EOF。 我尝试使用 Ionic.Zlib 而不是 System.IO.Compression 但结果是一样的。这些文件似乎没有以任何方式损坏,使用 Winrar 解压缩它们。

如果有人知道如何解决这个问题,我将不胜感激。 谢谢

您可以在此处下载示例文件: http://www.adjustyourset.tv/fms_6F9E_20120621_0001.log.gz

这是我的解压功能:

    public static bool DecompressGZip(String fileRoot, String destRoot)
    {
        try
        {
            using (FileStream fileStram = new FileStream(fileRoot, FileMode.Open, FileAccess.Read))
            {
                using (FileStream fOutStream = new FileStream(destRoot, FileMode.Create, FileAccess.Write))
                {
                    using (GZipStream zipStream = new GZipStream(fileStram, CompressionMode.Decompress, true))
                    {
                        byte[] buffer = new byte[4096];
                        int numRead;

                        while ((numRead = zipStream.Read(buffer, 0, buffer.Length)) != 0)
                        {
                            fOutStream.Write(buffer, 0, numRead);
                        }
                        return true;
                    }
                }

            }
        }
        catch (Exception ex)
        {
            LogUtils.SaveToLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), "Eror decompressing " + fileRoot + " : " + ex.Message, Constants.systemLog, 209715200, 6);
            return false;
        }
    }

【问题讨论】:

  • 你确实意识到你不需要像这样嵌套使用?您可以省略前两个之后的大括号(仅保留第三组),并将所有三个 using 直接放在彼此下方,并具有相同的缩进。
  • 我遇到了和你一样的问题 - 这很奇怪 - 我会仔细看看。
  • 我尝试使用 7-Zip 将日志文件压缩为 .gz 并通过上述方法成功解压,而来自发布链接的存档仅用第一行解压,不同之处在于一个压缩在UNIX 机器(来自链接的那个),而另一台是在 Windows 机器上压缩的,如果你在 7-Zip 中打开它或使用 WinRar 查看属性,你会看到“Host-OS”是“MS-DOS”,而在如果是来自链接的存档,它是“UNIX”,其他成功解压缩的存档是否也来自 UNIX?

标签: c# gzip gzipstream


【解决方案1】:

我在过去的 45 分钟里一直在思考这个问题,但我无法解释为什么它不起作用。不知何故,DeflateStream 类没有正确解码您的数据。我编写了自己的 GZip 解析器(如果有人想检查它,我可以分享代码),它读取所有标题并检查它们的有效性(以确保那里没有有趣的东西),然后使用 DeflateStream 膨胀实际数据,但有了你的文件,它仍然只是让我第一行。

如果我使用 GZipStream 使用您的日志文件重新压缩(在第一次使用 winrar 解压缩后),那么我自己的解析器和您自己的示例都可以再次解压缩它。

网上似乎有一些关于 Microsoft 实施 Deflate (http://www.virtualdub.org/blog/pivot/entry.php?id=335) 的批评,所以您可能发现了其中之一怪癖。

不过,解决您的问题的一个简单方法是切换到 SharZipLib (http://www.icsharpcode.net/opensource/sharpziplib/),我试过了,它可以很好地解压您的文件。

    public static void DecompressGZip(String fileRoot, String destRoot)
    {
        using (FileStream fileStram = new FileStream(fileRoot, FileMode.Open, FileAccess.Read))
        using (GZipInputStream zipStream = new GZipInputStream(fileStram))
        using (StreamReader sr = new StreamReader(zipStream))
        {
            string data = sr.ReadToEnd();
            File.WriteAllText(destRoot, data);
        }
    }

【讨论】:

  • 谢谢,我试过 SharZipLib,但我得到了相同的结果。你能请张贴你的功能吗?我可能只是错过了一些东西。
  • 抱歉,不需要该功能,已修复。奇迹般有效。谢谢。
  • 不,但你是对的,一个样本对找到这个线程的其他人有好处,所以我添加了它。
  • 澄清一下,它只适用于 SharpZipLib 版本 0.86.0.518。发行说明建议此版本添加了Multi-member gzip 支持,因此这里真正的问题可能是 .NET 只能读取多成员 gzip 文件的第一个成员。
  • 我从 Google 云存储中提取的文件遇到了完全相同的问题。目前只有SharZipLib可以解压。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多