如何在C#中使用SevenZipSharp / Unrar知道哪个rar在多rar档案中是第一个?

我试图在C#WinForms .NET 3.5中使用SevenZipSharp或/和Unrar库。 我有多个rar档案有这个问题,例如有不同的命名:

  • .rar,r01,r02,r03等(这很容易)
  • somefile01.rar,somefile02.rar,somefile03.rar

  • .001,.002,003等。

如果我将Unrar或SevenZipSharp指向错误的存档,它将解压缩该特定存档并将其余部分解压缩。 所以我必须指出正确的一个(除非我做错了什么)。

检查的最佳方法是什么? 现在我正在检查目录中是否有多个.rar文件然后如果是这样我检查01.rar。 如果只有一个和.rar和几个r01然后我得到.rar但这似乎有点不对。

有没有办法让SevenZip或Unrar通过指向任何.rar文件实际解压整个多rar包? 或.001?

疯狂的男孩

编辑:

我尝试使用以下代码来获取一个答案中建议的信息,但它无法提供承诺的信息。 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()); } } 

我相信您可以使用SevenZipExtractor.ArchiveFileData属性,然后遍历标题数据以查找相关信息。

RAR头结构的一部分 :

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:

我已经创建了一种猜测和validation第一卷的方法:

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

它既快又脏,但有效,你可以根据自己的需要进一步改进。

我希望这有帮助。

使用SharpCompress

 using (var archive = RarArchive.Open("Rar.multi.part01.rar"))) { Assert.IsTrue(archive.IsMultipartVolume()); Assert.IsTrue(archive.IsFirstVolume()); }