如何使用C#中的SevenZipSharp / Unrar知道哪个rar首先出现在多rar档案中? [英] How to know which rar is first in multi rar archives using SevenZipSharp/Unrar in C#?

查看:177
本文介绍了如何使用C#中的SevenZipSharp / Unrar知道哪个rar首先出现在多rar档案中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to use SevenZipSharp or/and Unrar library in C# WinForms .NET 3.5. I have this problem with multi rar archives that have diffrent naming for example:


  • .rar,r01,r02,r03等(本

  • somefile01.rar,somefile02.rar,somefile03.rar

  • .rar, r01, r02, r03 and so on (this is easy)
  • somefile01.rar, somefile02.rar, somefile03.rar

.001,。 002、003,依此类推。

.001, .002, 003 and so on.

如果我将Unrar或SevenZipSharp指向错误的档案,它将解压缩该特定档案并整理好行李。因此,我必须指出正确的人(除非我做错了什么)。

If i point Unrar or SevenZipSharp to wrong archive it will unpack that particular archive and leave rest unpacked. So i have to point the right one (unless i am doing something wrong).

什么是最好的检查方法?现在,我正在检查目录中是否有多个.rar文件,然后如果是,请检查01.rar。如果只有一个,.rar和几个r01,那么我会得到.rar,但这似乎有些错误。

What would be the best way to check for that? For now i am checking if there are more then one .rar files inside directory then if so i check for 01.rar. If there's only one and .rar and couple of r01 then i get .rar but this seems a bit wrong.

有没有一种方法可以使SevenZip或Unrar仅通过指向任何.rar文件来实际解压缩整个多rar软件包?还是.001?

Is there a way to make SevenZip or Unrar to actually unpack whole multi rar pack just by pointing to any .rar file? or .001 ?

MadBoy

编辑:

我尝试过使用以下代码来获取一个答案中建议的信息,但是它无法传递承诺的信息。 extr.ArchiveFileData对于zip返回0,对于任何提供的rar(无论是rar还是r01),返回32。

I tried to use following code to get information as suggested in one answer but it fails to deliver promised information. extr.ArchiveFileData returns 0 for zip, and 32 for any provided rar whether it's rar or 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());
            }
        }


推荐答案

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

I believe that you could use SevenZipExtractor.ArchiveFileData property and then iterate through header data to find the relevant information.

Part RAR标头结构


HEAD_FLAGS位标志:2个字节

HEAD_FLAGS Bit flags: 2 bytes

            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:(

When I downloaded SevenZipSharp(1 hour ago) and found that SevenZipExtractor class contains a property that lists every file in volume (VolumeFileNames). I thought 'Great! That was easy!', well... it's never that easy. It seems that VolumeFileNames works perfectly but only if you point it to the first rar in volume :(

我创建了一种方法来猜测和验证第一卷:

I've created a method to guess and verify the first volume :

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

快速但很脏,但是可以根据需要进一步完善。

It's quick&dirty but works and you can refine it further according to your needs.

我希望这会有所帮助。

这篇关于如何使用C#中的SevenZipSharp / Unrar知道哪个rar首先出现在多rar档案中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆