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

What is the simplest way to decompress a ZIP buffer in C#?

当我在 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但是不太明白:

How do I compress/decompress files in memory?

Use a memory stream when creating the Zip stream!

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

You can get the resulting data with memory stream methods ToArray or GetBuffer.

ToArray is the cleaner and easiest to use correctly with the penalty of duplicating allocated memory. GetBuffer returns a raw buffer raw and so you need to account for the true length yourself.

See the framework class library help for more information.

我不知道这段代码是用于压缩还是解压,如果outputMemStream表示压缩流或未压缩流。我真的希望有一种像 zlib 中那样易于理解的方式。如果你能帮助我,非常感谢。

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

假设您有一个字节数组 (byte []) 代表内存中的 ZIP 文件,您必须实例化一个 ZipArchive 对象,该对象将用于读取该字节数组并将它们解释为 ZIP您要加载的文件。如果检查 ZipArchive class' available constructors in documentation, you will see that they require a stream object from which the data will be read. So, first step would be to convert your byte [] array to a stream that can be read by the constructors, and you can do this by using a MemoryStream 对象。

下面是一个示例,说明如何列出在内存中表示为字节数组的 ZIP 存档内的所有条目:

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

using (var inputStream = new MemoryStream(zipArchiveBytes))
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 实例。此 class 提供的属性允许您从 ZIP 存档中检索文件的原始长度、压缩长度、名称等信息。

为了读取包含在 ZIP 文件中的特定文件,您可以在 ZIP 存档中使用 ZipArchiveEntry.Open(). The following exemplifies how to open a specific file from an archive, if you have its FullName

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();
    }
}

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