¿Cómo saber qué rar es el primero en archivos rar múltiples usando SevenZipSharp / Descomprimir en C #?

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

  •  22-09-2019
  •  | 
  •  

Pregunta

Estoy tratando de utilizar SevenZipSharp y / o biblioteca Descomprimir en C # .NET Windows Forms 3.5. Tengo este problema con múltiples archivos rar que tienen nombres diffrent por ejemplo:

  • .rar, R01, R02, R03 y así sucesivamente (esto es fácil)
  • somefile01.rar, somefile02.rar, somefile03.rar

  • 0.001, 0.002, 003 y así sucesivamente.

Si señalo al archivo mal Descomprimir o SevenZipSharp va a descomprimir ese archivo y el permiso especial de descanso desempaquetado. Así que tengo que señalar la correcta (a menos que yo estoy haciendo algo mal).

¿Cuál sería la mejor forma de comprobar que? Por ahora estoy comprobando si hay más de uno .rar dentro del directorio a continuación, si es así puedo comprobar si hay 01.rar. Si sólo hay una y .rar y un par de R01 cuando me siento .rar pero esto parece un poco mal.

¿Hay una manera de hacer SevenZip o Descomprimir el paquete rar a múltiples toda realidad de desempaquetado con sólo apuntar a cualquier archivo .rar? o 0.001?

MadBoy

EDIT:

He intentado utilizar el código siguiente para obtener información como se sugiere en una respuesta pero no puede entregar información prometida. extr.ArchiveFileData devuelve 0 para Zip, y 32 para cualquier rar proporcionado si se trata de RAR o 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());
            }
        }
¿Fue útil?

Solución

Creo que se puede utilizar la propiedad SevenZipExtractor.ArchiveFileData y luego iterar a través de los datos de cabecera para encontrar la información relevante.

Parte de la RAR cabecera estructura :

  

HEAD_FLAGS banderas de bits: 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

Editar

Cuando descargué SevenZipSharp (hace 1 hora) y se encontró que la clase SevenZipExtractor contiene una propiedad que las listas de todos los archivos en el volumen (VolumeFileNames). Pensé 'Great! Eso fue fácil!', Así ... nunca es tan fácil. Parece que VolumeFileNames funciona perfectamente pero sólo si apunta a la primera rar en el volumen: (

El wokraround:

He creado un método para adivinar y verificar el primer volumen:

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

Es rápido y sucio, pero funciona y se puede afinar aún más de acuerdo a sus necesidades.

Espero que esto ayude.

Otros consejos

Uso SharpCompress

using (var archive = RarArchive.Open("Rar.multi.part01.rar")))
{
    Assert.IsTrue(archive.IsMultipartVolume());
    Assert.IsTrue(archive.IsFirstVolume());
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top