如何使用SevenZipSharp提取多卷7z文件?

时间:2016-03-20 15:56:49

标签: c# .net vb.net 7zip sevenzipsharp

我使用 SevenZipSharp 库生成了一个多卷 7z 文件。

我遇到的问题是,当我尝试提取文件时,我得到一个关于无效转换的例外:

  

无法投射对象

     类型'SevenZip.InMultiStreamWrapper'输入'SevenZip.InStreamWrapper'。

抛出异常的方法是SevenZipExtractor.Check()

这是用Vb.Net编写的示例代码,用于重现提取问题,但我也可以接受C#解决方案:

Public Overridable Function Extract(ByVal sourceFilePath As String,
                                    ByVal outputDirectorypath As String,
                                    ByVal password As String) As String

    If String.IsNullOrEmpty(password) Then
        Me.extractor = New SevenZipExtractor(sourceFilePath)
    Else
        Me.extractor = New SevenZipExtractor(sourceFilePath, password)
    End If

    ' Check for password matches doing an integrity check.
    If Me.extractor.Check() Then
        ' Start the extraction.
        Me.extractor.ExtractArchive(outputDirectorypath)

    Else
        Throw New Exception(
              "Failed to extract, maybe the provided password does not match?.")

    End If

    Return outputDirectorypath

End Function

如果我忽略完整性检查,使用设置了密码的多卷文件,那么我无法提取它,因为发生了另一个异常......

Probablly是他们的源代码中的一个错误,但我要求确定,因为该库不支持提取多卷文件非常奇怪...

1 个答案:

答案 0 :(得分:4)

  

Probablly是源代码中的一个错误

情况确实如此。

查看SevenZipExtractor.cs源代码,我们看到以下行(在方法finally块内,因此它始终执行):

((InStreamWrapper)_archiveStream).Dispose();

其中_archiveStream是类型IInStream的类字段(注意I),这是一种不是从IDisposable派生的接口类型,因此没有{ {1}}方法。

更深入,我们可以看到它是使用DisposeInStreamWrapper类的实例初始化的。虽然它们都共享公共基类InMultiStreamWrapper,但后者不会继承前者,因此会抛出异常。

如果您愿意修改源代码,那么修复它很容易。只需将以上行替换为:

StreamWrapper

然而

  

如果我忽略完整性检查,使用设置了密码的多卷文件,那么我无法提取它,因为发生了另一个异常......

他们不会在内部调用if (_archiveStream is IDisposable) ((IDisposable)_archiveStream).Dispose(); 方法,在调用Check之前,您是否应该调用Check之间不存在任何关系。所以我怀疑修复上面的bug会阻止你所说的另一个例外。