Come sapere quale rar è il primo in multi archivi rar utilizzando SevenZipSharp / Unrar in C #?
Domanda
Sto cercando di utilizzare SevenZipSharp o / e la biblioteca Unrar in C # WinForms .NET 3.5. Ho questo problema con i multi archivi RAR che hanno denominazione differente, ad esempio:
- .rar, r01, R02, R03 e così via (questo è facile)
-
somefile01.rar, somefile02.rar, somefile03.rar
-
.001, .002, 003 e così via.
Se io punto Unrar o SevenZipSharp archiviare sbagliato si scompattare quel particolare archivio e lasciare riposare spacchettato. Quindi devo puntare il giusto (a meno che non sto facendo qualcosa di sbagliato).
Quale sarebbe il modo migliore per verificare la presenza di questo? Per ora sto controllando se ci sono più di un file .rar dentro directory allora se così posso controllare per 01.rar. Se c'è una sola e .rar e un paio di R01 allora ottengo .rar ma questo sembra un po 'sbagliato.
C'è un modo per rendere SevenZip o Unrar per disfare in realtà tutto il pacchetto a più rar semplicemente puntando a qualsiasi file .rar? o .001?
MadBoy
EDIT:
Ho cercato di usare codice riportato di seguito per ottenere informazioni come suggerito in una risposta, ma non riesce a fornire informazioni promessa. extr.ArchiveFileData restituisce 0 per la chiusura lampo, e il 32 per qualsiasi condizione rar che si tratti di 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());
}
}
Soluzione
Credo che si potrebbe usare proprietà SevenZipExtractor.ArchiveFileData
e poi scorrere i dati di intestazione per trovare le informazioni pertinenti.
Una parte della struttura di RAR intestazione :
HEAD_FLAGS bandiere bit: 2 byte
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
Modifica
Quando ho scaricato SevenZipSharp (1 ora fa) e ha scoperto che la classe SevenZipExtractor
contiene una proprietà che elenca tutti i file di volume (VolumeFileNames
). Ho pensato 'Grande! E 'stato facile!', Beh ... non è mai così facile. Sembra che VolumeFileNames
funziona perfettamente, ma solo se si punta alla prima rar in termini di volume: (
Il wokraround:
Ho creato un metodo di indovinare e verificare il primo 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;
}
È veloce e sporco, ma opere ed è possibile raffinare ulteriormente in base alle proprie esigenze.
Spero che questo aiuta.
Altri suggerimenti
using (var archive = RarArchive.Open("Rar.multi.part01.rar")))
{
Assert.IsTrue(archive.IsMultipartVolume());
Assert.IsTrue(archive.IsFirstVolume());
}