我使用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
如果我忽略完整性检查,使用设置了密码的多卷文件,那么我无法提取它,因为发生了另一个异常......
可能是他们源代码中的一个错误,但我要求确定,因为库不支持提取多卷文件非常奇怪......
可能是其源代码中的错误
事实确实如此。
查看 SevenZipExtractor.cs源代码,我们看到以下行(在方法finally
块内,因此它始终执行):
((InStreamWrapper)_archiveStream).Dispose();
其中_archiveStream
是类型为IInStream
的类字段(注意I
),这是一个不是从IDisposable
派生的接口类型,因此没有Dispose
方法。
更深入地,我们可以看到它是用InStreamWrapper
或InMultiStreamWrapper
类的实例初始化的。虽然它们都共享共同的基类StreamWrapper
,但后者不继承前者,因此强制转换例外。
如果您愿意修改源代码,修复它非常容易。只需将上面的行替换为:
if (_archiveStream is IDisposable)
((IDisposable)_archiveStream).Dispose();
然而
如果我忽略完整性检查,使用设置了密码的多卷文件,那么我无法提取它,因为发生了另一个异常......
它们不会在内部调用 Check
方法,并且在调用 ExtractArchive
之前是否调用 Check
应该没有任何关系。所以我怀疑修复上述错误是否会阻止您正在谈论的另一个异常。