¿Cómo saber qué rar es el primero en archivos rar múltiples usando SevenZipSharp / Descomprimir en C #?
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());
}
}
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());
}