1

我在用 c# 编写的Windows Mobile应用程序上使用 SharpZipLib 进行 gzip

我有这个代码

public static bool gzDecompressFile(String inputFilePath, String outputFilePath)
        {
            if (!File.Exists(inputFilePath))
                return false;

            if (File.Exists(outputFilePath))
                File.Delete(outputFilePath);


            FileStream fs = File.OpenRead(inputFilePath);
            FileStream fsOut = File.OpenWrite(outputFilePath);

            GZipInputStream gzipIn = new GZipInputStream(fs);

            // Compress file in 1kb chunks
            byte[] chunk = new byte[1024];
            int read = 1;

            while (read > 0)
            {
                read = gzipIn.Read(chunk, 0, chunk.Length);

                if (read > 0)
                {
                    fsOut.Write(chunk, 0, read);
                }
            }

            fsOut.Close();
            fs.Close();

            return true;
        }

对于 1.6MB --> 7MB 的解压需要 4-5 分钟。
你知道一个更好的紧凑框架吗?

4

3 回答 3

2

在 4 分钟内将 1.6MB 解压缩到 7MB 非常慢。

想到的一些项目:

  1. 您是否尝试过更改工作缓冲区的大小?1KB 是非常保守的恕我直言。您可能会遇到 GZip 解压缩算法的性能问题(但这只是 WAG)。
  2. 是否有临时文件被存储,如果有,在哪里?它们是在内存中还是在存储设备上?如果在存储设备上,哪一个可能具有不同的性能特征。
  3. 您可以通过双缓冲来提高性能。这是通过创建两个缓冲区来工作的,当一个缓冲区从读取中填充时,另一个缓冲区正在被写入刷新(乒乓效应,需要异步代码)。它只会与最慢的操作(解压缩的流读取)一样快,但您可能几乎可以消除累积的写入延迟。

我们最初从 SharpLibZip 开始,但切换到商业Xceed ZIP.NET库以利用批处理功能(以及对 .NET 和 .NET Compact Frameworks 的支持)。Xceed 库也支持 GZip。即使在我们古老的 400 MHz Windows CE 4.2 设备上,我们也只需要大约 20-30 秒来解压缩一个 6 MB 文件(尽管使用 XCeed ZIP.NET 在 ZIP 中)。

另外,如果我没记错的话,我相信 .NET Compact Framework 支持 GZip。附带说明一下,将 FileStreams 放在 using 语句中,以确保在方法中间发生异常时关闭它们。

于 2010-02-23T05:26:22.267 回答
1

压缩是非常占用 CPU 的。可能是……这就是需要多长时间。

试试 DotNetZip - 不确定是否更快,但它是免费的,易于尝试。DotNetZip 中有一个 GZipStream 可以替代 .NET BCL 中的 GZipStream。

由于您正在执行 GZIP 而不是 ZIP,因此您只需要 Ionic.Zlib.dll,而不需要 Ionic.Zip.dll 。前者是后者的严格子集。


编辑:代码示例

using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress))
{
    using (var raw = System.IO.File.Create(outputFile))
    {
        using (Stream compressor = new GZipStream(raw, CompressionMode.Compress))
        {
            byte[] buffer = new byte[WORKING_BUFFER_SIZE];
            int n;
            while ((n= input.Read(buffer, 0, buffer.Length)) != 0)
            {
                compressor.Write(buffer, 0, n);
            }
        }
    }
}

(上述代码中的 GZipStream 由 Ionic.Zlib.dll 提供。)

于 2010-02-15T22:46:21.133 回答
0

我使用 ZIP 组件作为 Resco Mobile Toolkit 的一部分:http ://www.resco.net/developer/mobileformstoolkit/overview.aspx

该工具包的价格可能令人望而却步——这取决于您是否需要任何其他控件。

于 2010-02-13T16:58:11.287 回答