在C#中解压缩ZIP缓冲区的最简单方法是什么?

时间:2018-10-12 01:45:53

标签: c# zlib sharpziplib

当我在C / C ++中使用 zlib 时,我有一个简单的方法uncompress,它仅需要两个缓冲区,而没有其他缓冲区。其定义是这样的:

int uncompress (Bytef *dest, uLongf *destLen, const Bytef *source,
uLong sourceLen); 
/*
Decompresses the source buffer into the destination buffer.  sourceLen is    the byte length of the source buffer.  Upon entry,
destLen is the total size    of the destination buffer, which must be
large enough to hold the entire    uncompressed data.  (The size of
the uncompressed data must have been saved    previously by the
compressor and transmitted to the decompressor by some    mechanism
outside the scope of this compression library.) Upon exit, destLen   
is the actual size of the uncompressed data.

uncompress returns Z_OK if success, Z_MEM_ERROR if there was not    enough memory, Z_BUF_ERROR if there was not enough room in the output 
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
In    the case where there is not enough room, uncompress() will fill
the output    buffer with the uncompressed data up to that point.
*/

我想知道C#是否也有类似的方法。我检查了 SharpZipLib FAQ 如下,但不太了解:

  

如何压缩/解压缩内存中的文件?

     

在创建Zip流时使用内存流!

MemoryStream outputMemStream = new MemoryStream();
using (ZipOutputStream zipOutput = new ZipOutputStream(outputMemStream)) {   
// Use zipOutput stream as normal    
...  
     

您可以使用内存流方法ToArray或GetBuffer获得结果数据。

     

ToArray是更干净,最容易正确使用的惩罚方法   复制分配的内存。 GetBuffer返回原始缓冲区raw   因此您需要自己计算真实长度。

     

有关更多信息,请参见框架类库帮助。

如果outputMemStream是压缩流还是未压缩流,我无法弄清楚这段代码是用于压缩还是解压缩。我真的希望zlib中有一种易于理解的方式。非常感谢您能为我提供帮助。

1 个答案:

答案 0 :(得分:2)

查看ZipArchive class,我认为它具有完成zip文件的内存内解压缩所需的功能。

假设您有一个表示内存中ZIP文件的字节数组(byte []),则必须实例化一个ZipArchive对象,该对象将用于读取该字节数组并将其解释为您的ZIP文件希望加载。如果您查看文档中的ZipArchive class' available constructors,将会看到它们需要一个流对象,可以从中读取数据。因此,第一步将是将byte []数组转换为构造函数可以读取的流,并且可以使用MemoryStream对象来实现。

这是一个示例,该示例如何列出ZIP归档文件中以内存为字节数组表示的所有条目:

byte [] zipArchiveBytes = ...;   // Read the ZIP file in memory as an array of bytes

using (var inputStream = new MemoryStream(fileBytes))
using (var zipArchive = new ZipArchive(inputStream, ZipArchiveMode.Read))
{
    Console.WriteLine("Listing archive entries...");
    foreach (var archiveEntry in zipArchive.Entries)
        Console.WriteLine($"   {archiveEntry.FullName}");
}

ZIP存档中的每个文件都将表示为ZipArchiveEntry实例。此类提供的属性使您可以检索信息,例如ZIP存档中文件的原始长度,压缩长度,名称等。

为了读取ZIP文件中包含的特定文件,可以使用ZipArchiveEntry.Open()。如果您的FullName位于ZIP存档中,则以下示例说明了如何从存档中打开特定文件:

ZipArchiveEntry archEntry = zipArchive.GetEntry("my-folder-inside-zip/dog-picture.jpg");
byte[] readResult;
using (Stream entryReadStream = archEntry.Open())
{
    using (var tempMemStream = new MemoryStream())
    {
        entryReadStream.CopyTo(tempMemStream);
        readResult = tempMemStream.ToArray();
    }
}

此示例读取给定的文件内容,并将其作为字节数组(存储在byte[] readResult变量中)返回,然后您可以根据需要使用它们。