كيف تعرف أي RAR هي الأولى في أرشيفات RAR المتعددة باستخدام SevenZipSharp/unar في C#؟
سؤال
أحاول استخدام مكتبة 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());
}