3

C#WinForms.NET3.5でSevenZipSharpまたは/およびUnrarライブラリを使用しようとしています。たとえば、名前が異なるマルチrarアーカイブでこの問題が発生します。

  • .rar、r01、r02、r03など(これは簡単です)
  • somefile01.rar、somefile02.rar、somefile03.rar

  • .001、.002、003など。

UnrarまたはSevenZipSharpに間違ったアーカイブを指定すると、その特定のアーカイブが解凍され、残りは解凍されたままになります。だから私は正しいものを指さなければなりません(私が何か間違ったことをしているのでない限り)。

それをチェックするための最良の方法は何でしょうか?今のところ、ディレクトリ内に複数の.rarファイルがあるかどうかを確認しています。ある場合は、01.rarを確認します。r01が1つと.rarと2つしかない場合は、.rarを取得しますが、これは少し間違っているようです。

.rarファイルをポイントするだけで、SevenZipまたはUnrarを作成してマルチrarパック全体を実際に解凍する方法はありますか?または.001?

イケナイ人

編集:

次のコードを使用して、1つの回答で提案されている情報を取得しようとしましたが、約束された情報を提供できません。extr.ArchiveFileDataは、zipの場合は0を返し、rarまたはr01のいずれであっても、提供されたrarの場合は32を返します。

        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());
            }
        }
4

2 に答える 2

2

プロパティを使用し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:

私は最初のボリュームを推測して検証するメソッドを作成しました:

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

迅速で汚れていますが、機能し、必要に応じてさらに改良することができます。

これがお役に立てば幸いです。

于 2010-02-23T10:53:38.857 に答える
1

SharpCompressの使用

using (var archive = RarArchive.Open("Rar.multi.part01.rar")))
{
    Assert.IsTrue(archive.IsMultipartVolume());
    Assert.IsTrue(archive.IsFirstVolume());
}
于 2011-09-28T12:15:52.180 に答える