使用 GZipStream 解压缩仅返回第一行



我一直在研究解析第三方 fms 日志的函数。日志在 Gzip 中,所以我使用解压缩功能适用于我们使用的任何其他 Gzip 文件。

解压缩这些文件时,我只得到压缩文件的第一行,没有例外,它只是找不到其余的字节,就好像第一行有一个EOF一样。我尝试使用Ionic.Zlib而不是System.IO.Compress,但结果是一样的。这些文件似乎没有以任何方式损坏,使用 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;
        }
    }

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

如果我使用 GZipStream 使用您的日志文件重新压缩(首先使用 winrar 解压缩它之后),那么它再次解压缩,无论是我自己的解析器还是您自己的示例。

网络上似乎有一些关于微软实现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);
        }
    }

最新更新