我正在尝试在C#WinForms .NET 3.5中使用SevenZipSharp或/和Unrar库。我有多个rar档案的问题,例如:
somefile01.rar,somefile02.rar,somefile03.rar
.001,.002,003等。
如果我将Unrar或SevenZipSharp指向错误的存档,它将解压缩该特定存档并将其余部分解压缩。所以我必须指出正确的一个(除非我做错了什么)。
最好的检查方法是什么?现在我正在检查目录中是否有多个.rar文件然后如果是这样我检查01.rar。如果只有一个和.rar和几个r01然后我得到.rar但这似乎有点不对。
有没有办法让SevenZip或Unrar通过指向任何.rar文件来实际解压整个多rar包?或.001?
MadBoy
编辑:
我尝试使用以下代码来获取一个答案中建议的信息,但它无法提供承诺的信息。 extr.ArchiveFileData为zip返回0,为任何提供的rar返回32,无论是rar还是r01。
using (SevenZipExtractor extr = new SevenZipExtractor(fileName)) {
foreach (var var in extr.ArchiveProperties) {
string attributes = var.Name;
object test = var.Value;
if (test == null) {
test = "THIS";
}
MessageBox.Show(attributes.ToString(), test.ToString());
}
foreach (var var in extr.ArchiveFileData) {
MessageBox.Show(var.Attributes.ToString());
}
}
答案 0 :(得分:2)
我相信您可以使用SevenZipExtractor.ArchiveFileData
属性,然后遍历标题数据以查找相关信息。
RAR header structure的一部分:
HEAD_FLAGS位标志:2个字节
0x0001 - Volume attribute (archive volume) 0x0002 - Archive comment present RAR 3.x uses the separate comment block and does not set this flag. 0x0004 - Archive lock attribute 0x0008 - Solid attribute (solid archive) 0x0010 - New volume naming scheme (\'volname.partN.rar\') 0x0020 - Authenticity information present RAR 3.x does not set this flag. 0x0040 - Recovery record present 0x0080 - Block headers are encrypted 0x0100 - First volume (set only by RAR 3.0 and later) other bits in HEAD_FLAGS are reserved for internal use
修改:
当我下载SevenZipSharp(1小时前)时发现SevenZipExtractor
类包含一个列出卷中每个文件的属性(VolumeFileNames
)。我以为'太棒了!这很容易!',嗯......从来没有那么容易。似乎VolumeFileNames
完美无缺,但只有当你将它指向第一个rar时:(
Wokraround:
我已经创建了一种猜测和验证第一卷的方法:
private static string LocateFirstVolume(string filename)
{
var isVolume = false;
var parts = 1u;
using (var extractor = new SevenZipExtractor(filename))
{
isVolume =
extractor.ArchiveProperties.Any(x =>
x.Name.Equals("IsVolume") && x.Value.Equals(true));
parts = (
from x in extractor.ArchiveProperties
where x.Name.Equals("Number of volumes")
select (uint)x.Value).DefaultIfEmpty(1u).SingleOrDefault();
}
if (!isVolume)
return null;
if (parts > 1)
return filename;
if (!Path.GetExtension(filename)
.Equals(".rar", StringComparison.OrdinalIgnoreCase))
{
var rarFile =
Path.Combine(
Path.GetDirectoryName(filename),
Path.GetFileNameWithoutExtension(filename) + ".rar");
if (File.Exists(rarFile))
{
var firstVolume = LocateFirstVolume(rarFile);
if (firstVolume != null)
{
return firstVolume;
}
}
}
var directoryFiles = Directory.GetFiles(Path.GetDirectoryName(filename));
foreach (var directoryFile in directoryFiles)
{
var firstVolume = LocateFirstVolume(directoryFile);
if (firstVolume != null)
{
using (var extractor = new SevenZipExtractor(firstVolume))
{
if (extractor.VolumeFileNames.Contains(filename))
{
return firstVolume;
}
}
}
}
return null;
}
它快速而且肮脏但有效,你可以根据自己的需要进一步改进它。
我希望这会有所帮助。
答案 1 :(得分:1)
using (var archive = RarArchive.Open("Rar.multi.part01.rar")))
{
Assert.IsTrue(archive.IsMultipartVolume());
Assert.IsTrue(archive.IsFirstVolume());
}