简体   繁体   English

Ziparchive 解压多部分 zip 文件

[英]Ziparchive unpack multipart zipfile

I'm looking to unzip a multipart zipfile through ZipArchive.我正在寻找通过 ZipArchive 解压缩多部分 zipfile。 Unzipping one 'standalone' zipfile works but if I try to unzip the first file it just throws an error.解压缩一个“独立”zip 文件是可行的,但如果我尝试解压缩第一个文件,它只会抛出一个错误。 It works like this in windows explorer (Just unzip the first file), so I guessed it might work since I can't find any other ways online.它在 windows 资源管理器中是这样工作的(只需解压缩第一个文件),所以我猜它可能有效,因为我在网上找不到任何其他方法。

using (ZipArchive archive = new ZipArchive(fs)) {
    archive.ExtractToDirectory(tempLocation, true);
}

But, maybe this is an XY Problem , so I'm using it as a simplified way of chunkedfile-downloads.但是,也许这是一个XY 问题,所以我将它用作分块文件下载的简化方式。 We're using this for an updateservice, which downloads the contents of the update.我们将其用于更新服务,它下载更新的内容。 To be a bit flexible we would use (multipart)zipfiles.为了灵活一点,我们将使用(多部分)zip 文件。 If this is the wrong approach, please do tell me.如果这是错误的方法,请告诉我。

EDIT: After figuring out that the first error was PEBCAK I got the error that "Splitted or spread archives aren't supported".编辑:在发现第一个错误是PEBCAK 之后,我得到了“不支持拆分或传播档案”的错误。

Are there any other Zipfile libraries that do support it?是否有任何其他支持它的 Zipfile 库?

I recommend using DotNetZip to accomplish what you want. 我建议使用DotNetZip来完成你想要的。

First you must combine all your ".zip.001" ".zip.002" ".zip.003" files into one huge file and then follow up on decompressing as normal: 首先,您必须将所有“.zip.001”“。zip.002”“。zip.003”文件合并到一个巨大的文件中,然后按照正常情况进行解压缩:

        string destFileName = @"C:\Temp\zip\finalHugeFile.zip";
        List<string> myMultiPartZip00xFiles = System.IO.Directory.GetFiles(@"C:\Temp\zip", "*.zip.*").ToList();

        using (Stream destStream = File.OpenWrite(destFileName))
        {
            foreach (string srcFileName in myMultiPartZip00xFiles)
            {
                using (Stream srcStream = File.OpenRead(srcFileName))
                {
                    srcStream.CopyTo(destStream);
                }
            }
        }

        // we extract here
        using (ZipFile zip = ZipFile.Read(destFileName))
        {
            foreach (ZipEntry entry in zip)
            {
                entry.Extract(@"C:\Temp\zip", ExtractExistingFileAction.OverwriteSilently);
            }
        }

Multipart zip is just a regular zip split into files.多部分 zip 只是一个常规的 zip 拆分成文件。 So we need a Stream that combines multiple files into one:所以我们需要一个Stream将多个文件合二为一:

var multiFileStream = new MultiFileStream(new[] { "a.001", "a.002" });
using var zip = new ZipArchive(multiFileStream);

// ...

public class MultiFileStream : Stream
{
    private readonly IList<string> _files;
    private int _fileIdx;
    private FileStream? _file;

    public MultiFileStream(IList<string> files)
    {
        _files = files;
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        while (true)
        {
            _file ??= File.OpenRead(_files[_fileIdx]);

            var res = _file.Read(buffer, offset, count);

            if (res > 0)
            {
                return res;
            }

            _file.Dispose();
            _file = null;

            if (_fileIdx < _files.Count - 1)
            {
                _fileIdx++;
            }
            else
            {
                return 0;
            }
        }
    }

    public override void Flush() => throw new NotSupportedException();
    public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
    public override void SetLength(long value) => throw new NotSupportedException();
    public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
    public override bool CanRead => true;
    public override bool CanSeek => false;
    public override bool CanWrite => false;
    public override long Length => throw new NotSupportedException();
    public override long Position
    {
        get => throw new NotSupportedException();
        set => throw new NotSupportedException();
    }
}

The other answer works, but a lot slower because of the temp file and all the copying (and with big archives you can even run out of disk space).另一个答案有效,但由于临时文件和所有复制(并且对于大档案,您甚至可能会耗尽磁盘空间),因此速度要慢得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM