كيف تعرف أي RAR هي الأولى في أرشيفات RAR المتعددة باستخدام SevenZipSharp/unar في C#؟

StackOverflow https://stackoverflow.com/questions/2317316

  •  22-09-2019
  •  | 
  •  

سؤال

أحاول استخدام مكتبة SevenZipSharp أو/و Unrar في C# Winforms .NET 3.5. لدي هذه المشكلة مع المحفوظات المتعددة RAR التي تسمية مختلفة على سبيل المثال:

  • .Rar ، R01 ، R02 ، R03 وما إلى ذلك (هذا سهل)
  • somefile01.rar ، somefile02.rar ، somefile03.rar

  • .001 ، .002 ، 003 وما إلى ذلك.

إذا قمت بتوجيه Unar أو 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());
            }
        }
هل كانت مفيدة؟

المحلول

أعتقد أنه يمكنك استخدام 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 (قبل ساعة واحدة) ووجدت ذلك SevenZipExtractor يحتوي الفصل على خاصية يسرد كل ملف في مستوى الصوت (VolumeFileNames). اعتقدت "عظيم! كان ذلك سهلاً! '، حسنًا ... إنه ليس بهذه السهولة. يبدو أن VolumeFileNames يعمل بشكل مثالي ولكن فقط إذا قمت بإشارته إلى أول RAR في الحجم :(

ووكروند:

لقد قمت بإنشاء طريقة لتخمين المجلد الأول والتحقق منه:

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());
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top