2010-02-23 28 views
2

我想在C#WinForms .NET 3.5中使用SevenZipSharp或/和Unrar庫。我有這個問題有不同勢命名例如多RAR壓縮文件:如何知道在C#中使用SevenZipSharp/Unrar的多rar檔案中哪個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?

MadBoy

編輯:

我嘗試使用下面的代碼作爲一個答案建議,但未能提供承諾的信息來獲取信息。 extr.ArchiveFileData返回0表示zip,32表示任何提供的rar,不管它是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()); 
      } 
     } 

回答

1

我相信你可以使用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; 
} 

這很快&骯髒,但工程,你可以根據你的需要進一步改進它

我希望這可以幫助。

+0

是否有Unrar.dll相同的信息,由於某種原因,我不能讓SevenZip庫解包001,002壓縮的存檔(不知道爲什麼)。也許新版本固定它,但沒有時間測試。 – MadBoy 2010-02-23 11:22:59

+0

我確定這些信息可以使用unrar.dll,RARReadHeader和RARReadHeaderEx是這些方法,但是我對這個主題還沒有更多的瞭解。 – Diadistis 2010-02-23 11:35:34

+0

請檢查更新後的問題,其中說明我使用了哪些代碼以及我得到的返回結果,似乎不起作用:/ – MadBoy 2010-02-23 19:03:07

1

使用SharpCompress

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

不錯。謝謝,會看到它如何。 – MadBoy 2011-09-28 13:12:21