如何使用zlib对文件进行膨胀.NET

本文关键字:膨胀 NET 文件 何使用 zlib | 更新日期: 2023-09-27 17:47:49

我正在使用zlib。NET库来尝试并膨胀由zlib压缩的文件(可能在Linux盒子上)。我在做什么:

zlib.ZInputStream zinput =
    new zlib.ZInputStream(File.Open(path, FileMode.Open, FileAccess.Read));
while (stopByte != (data = zinput.ReadByte()))
{
  // check data here
}
zinput.Close();

数据字节与压缩的数据字节匹配,所以我一定做错了什么。

如何使用zlib对文件进行膨胀.NET

除了在遇到异常时无法使用"using"语句关闭流之外,我觉得还可以。数据肯定被压缩了吗?你能在linux盒子上用zlib解压缩它吗?

看过源代码后,它非常可怕——例如,对int Read(buffer, offset, length)的调用最终会调用其内部int Read()方法length次。考虑到这种不稳定的开始,我不确定我是否会特别信任代码,但我希望它至少能稍微运行!你试过使用SharpZipLib吗?

我似乎犯了一个错误,认为所有虚拟方法都被覆盖了,但事实并非如此。我用的是zlib。ZInputStream.ReadByte(),它只是继承的Stream.Read字节(),不做任何膨胀。

我用了zlib。改为ZInputStream.Read(),它的工作方式与它应该的一样。

跳过zlib标头(前两个字节,78 9C),然后使用.net中内置的DeflateStream,这对我来说很有效。

using(var input = File.OpenRead(...))
using(var output = File.Create(...))
{
    // if there are additional headers before the zlib header, you can skip them:
    // input.Seek(xxx, SeekOrigin.Current);
    if (input.ReadByte() != 0x78 || input.ReadByte() != 0x9C)//zlib header
        throw new Exception("Incorrect zlib header");
    using (var deflateStream = new DeflateStream(decryptedData, CompressionMode.Decompress, true))
    {
        deflateStream.CopyTo(output);
    }
}

下面的代码可以帮助你们。实例化对象并利用函数。

public class FileCompressionUtility
{
    public FileCompressionUtility()
    {
    }
    public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
    {
        byte[] buffer = new byte[2000];
        int len;
        while ((len = input.Read(buffer, 0, 2000)) > 0)
        {
            output.Write(buffer, 0, len);
        }
        output.Flush();
    }
    public void compressFile(string inFile, string outFile)
    {
        System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
        zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION);
        System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);
        try
        {
            CopyStream(inFileStream, outZStream);
        }
        finally
        {
            outZStream.Close();
            outFileStream.Close();
            inFileStream.Close();
        }
    }
    public void uncompressFile(string inFile, string outFile)
    {
        int data = 0;
        int stopByte = -1;
        System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
        zlib.ZInputStream inZStream = new zlib.ZInputStream(System.IO.File.Open(inFile, System.IO.FileMode.Open, System.IO.FileAccess.Read));
        while (stopByte != (data = inZStream.Read()))
        {
            byte _dataByte = (byte)data;
            outFileStream.WriteByte(_dataByte);
        }
        inZStream.Close();
        outFileStream.Close();
    }
}

我最近不幸地向包括IE7在内的各种浏览器和平台提供了以前使用php的zlib文档。一旦我发现文档是zlib’d而不是gzip’d(正如当时所认为的那样),我就在.NET Framework v4中以以下方式使用SharpZipLib(利用Stream.CopyTo):

public static byte[] DecompressZlib(Stream source)
{
    byte[] result = null;
    using (MemoryStream outStream = new MemoryStream())
    {
        using (InflaterInputStream inf = new InflaterInputStream(source))
        {
            inf.CopyTo(outStream);
        }
        result = outStream.ToArray();
    }
    return result;
}

我想我会把它放在这里,以防有人需要帮助使用SharpZipLib中的类。

仔细查看示例代码,它正在将数据从常规Filestream复制到ZOutputStream。解压缩必须通过该层进行。

private void decompressFile(string inFile, string outFile)
{
    System.IO.FileStream outFileStream = new System.IO.FileStream(outFile, System.IO.FileMode.Create);
    zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outFileStream);
    System.IO.FileStream inFileStream = new System.IO.FileStream(inFile, System.IO.FileMode.Open);          
    try
    {
        CopyStream(inFileStream, outZStream);
    }
    finally
    {
        outZStream.Close();
        outFileStream.Close();
        inFileStream.Close();
    }
}