سؤال

أحاول فك ضغط ملف مضغوط برمجياً.

لقد حاولت استخدام System.IO.Compression.GZipStream فئة في .NET، ولكن عندما يتم تشغيل تطبيقي (في الواقع اختبار وحدة) أحصل على هذا الاستثناء:

System.IO.InvalidDataException:الرقم السحري الموجود في رأس GZip غير صحيح.تأكد من أنك تمر في دفق GZip..

أدركت الآن أن أ .zip الملف ليس هو نفسه ملف .gz الملف، وذلك GZip ليست هي نفسها Zip.

ومع ذلك، نظرًا لأنني قادر على استخراج الملف عن طريق النقر المزدوج يدويًا على الملف المضغوط ثم النقر فوق الزر "استخراج جميع الملفات"، أعتقد أنه يجب أن تكون هناك طريقة للقيام بذلك في التعليمات البرمجية أيضًا.

لذلك حاولت استخدام Process.Start() مع المسار إلى الملف المضغوط كمدخل.يؤدي هذا إلى قيام تطبيقي بفتح نافذة تعرض محتويات الملف المضغوط.لا بأس بهذا، ولكن سيتم تثبيت التطبيق على خادم بدون وجود أي شيء للنقر على زر "استخراج كافة الملفات".

إذًا، كيف أجعل تطبيقي يستخرج الملفات الموجودة في الملفات المضغوطة؟

أم أن هناك طريقة أخرى للقيام بذلك؟أفضل القيام بذلك باستخدام التعليمات البرمجية، دون تنزيل أي مكتبات أو تطبيقات تابعة لجهات خارجية؛وقسم الأمن لا يبالي بهذا الأمر..

هل كانت مفيدة؟

المحلول

ولقد استخدمنا SharpZipLib بنجاح في العديد من المشاريع. وأنا أعلم أنه أداة طرف ثالث، ولكن يتم تضمين شفرة المصدر ويمكن أن توفر بعض البصيرة إذا اخترت لإعادة اختراع العجلة هنا.

نصائح أخرى

مع نت 4.5 يمكنك الآن فك ضغط الملفات باستخدام إطار عمل .NET:

using System;
using System.IO;

namespace ConsoleApplication
{
  class Program
  {
    static void Main(string[] args)
    {
      string startPath = @"c:\example\start";
      string zipPath = @"c:\example\result.zip";
      string extractPath = @"c:\example\extract";

      System.IO.Compression.ZipFile.CreateFromDirectory(startPath, zipPath);
      System.IO.Compression.ZipFile.ExtractToDirectory(zipPath, extractPath);
    }
  }
}

تم أخذ الكود أعلاه مباشرةً من وثائق Microsoft: http://msdn.microsoft.com/en-us/library/ms404280(v=vs.110).aspx

ZipFile موجود في الجمعية System.IO.Compression.FileSystem.(شكرًا nateirvin...انظر التعليق أدناه)

ل.نت 4.5+

ليس من المرغوب دائمًا كتابة الملف غير المضغوط على القرص.باعتباري أحد مطوري ASP.Net، كان علي أن أتعامل مع الأذونات لمنح حقوق تطبيقي للكتابة في نظام الملفات.من خلال العمل مع التدفقات في الذاكرة، يمكنني تجنب كل ذلك وقراءة الملفات مباشرة:

using (ZipArchive archive = new ZipArchive(postedZipStream))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
         var stream = entry.Open();
         //Do awesome stream stuff!!
    }
}

وبدلاً من ذلك، لا يزال بإمكانك كتابة الملف الذي تم فك ضغطه إلى القرص عن طريق الاتصال ExtractToFile():

using (ZipArchive archive = ZipFile.OpenRead(pathToZip))
{
    foreach (ZipArchiveEntry entry in archive.Entries)
    {
        entry.ExtractToFile(Path.Combine(destination, entry.FullName));
    }
} 

لاستخدام ال ZipArchive فئة، سوف تحتاج إلى إضافة مرجع إلى System.IO.Compression مساحة الاسم و System.IO.Compression.FileSystem.

والحرة، وأية ملفات DLL الخارجية. كل شيء في ملف واحد CS. تنزيل واحد هو مجرد ملف CS، وتحميل آخر هو السهل جدا أن نفهم سبيل المثال. فقط حاول ذلك اليوم ولا أستطيع أن أصدق كيف بسيط كان الإعداد. عملت في المحاولة الأولى، عدم وجود أخطاء، لا شيء.

https://github.com/jaime-olivares/zipstorer

استخدم المكتبة DotNetZip على http://www.codeplex.com/DotNetZip

<اقتباس فقرة>   

مكتبة فئة ومجموعة أدوات لمعالجة الملفات المضغوطة. استخدام VB، C # أو أي لغة .NET لإنشاء بسهولة، واستخراج، أو ملفات مضغوطة التحديث ...

     يعمل

وDotNetZip على أجهزة الكمبيوتر مع .NET Framework الكامل، ويعمل أيضا على الأجهزة النقالة التي تستخدم .NET Framework ضغط. إنشاء وقراءة الملفات المضغوطة في VB، C #، أو أي لغة .NET، أو أي بيئة البرمجة ...

     

وإذا كان كل ما نريده هو DeflateStream أفضل أو فئة GZipStream لتحل محل تلك التي بنيت في BCL .NET، لديها DotNetZip ذلك أيضا. هي DeflateStream DotNetZip وGZipStream المتاحة في التجمع مستقل، بناء على منفذ. NET من زليب. هذه التيارات تدعم مستويات الضغط وتقديم أداء أفضل بكثير من الطبقات المضمنة. وهناك أيضا ZlibStream لاستكمال مجموعة (RFC 1950، 1951، 1952) ...

String ZipPath = @"c:\my\data.zip";
String extractPath = @"d:\\myunzips";
ZipFile.ExtractToDirectory(ZipPath, extractPath);

لاستخدام فئة ZipFile، يجب إضافة مرجع إلى تجمع System.IO.Compression.FileSystem في المشروع

والملفات المضغوطة القياسية عادة استخدام خوارزمية يدحض.

لاستخراج الملفات من دون استخدام المكتبات طرف ثالث تستخدم DeflateStream. ستحتاج أكثر قليلا من المعلومات حول تنسيق أرشيف ملف مضغوط كما تقدم Microsoft فقط خوارزمية ضغط.

ويمكنك أيضا محاولة استخدام zipfldr.dll. ومن مكتبة ضغط مايكروسوفت (مضغوط المجلدات من إرسال إلى القائمة). يبدو أن مكتبة كوم لكنه لا يحملون وثائق. قد تكون قادرة على الحصول عليها للعمل معك من خلال التجريب.

هنا :

<اقتباس فقرة>   

التحف GZipStream مضغوط مكتوبة   إلى ملف مع ملحق .gz يمكن   يتم ضغط باستخدام العديد شيوعا   أدوات ضغط؛ ومع ذلك، هذه الفئة   لا توفر بطبيعتها   وظائف لإضافة الملفات إلى أو   استخراج الملفات من الرمز البريدي المحفوظات.

وأنا استخدم هذا إما الرمز البريدي أو بفك الملفات متعددة. لم يكن مطلوبا من الاشياء العبارة العادية، ولكن أنا استخدامها لتغيير طابع التاريخ وإزالة سفلية غير المرغوب فيها. يمكنني استخدام سلسلة فارغة في سلسلة ضغط >> zipPath بادئة شيء لجميع الملفات إذا لزم الأمر. أيضا، وعادة ما تعلق إما ضغط () أو فك ضغط () بناء على ما أقوم به.

using System;
using System.IO.Compression;
using System.IO;
using System.Text.RegularExpressions;

namespace ZipAndUnzip
{
    class Program
    {
        static void Main(string[] args)
        {
            var directoryPath = new DirectoryInfo(@"C:\your_path\");

            Compress(directoryPath);
            Decompress(directoryPath);
        }

        public static void Compress(DirectoryInfo directoryPath)
        {
            foreach (DirectoryInfo directory in directoryPath.GetDirectories())
            {
                var path = directoryPath.FullName;
                var newArchiveName = Regex.Replace(directory.Name, "[0-9]{8}", "20130913");
                newArchiveName = Regex.Replace(newArchiveName, "[_]+", "_");
                string startPath = path + directory.Name;
                string zipPath = path + "" + newArchiveName + ".zip";

                ZipFile.CreateFromDirectory(startPath, zipPath);
            }

        }

        public static void Decompress(DirectoryInfo directoryPath)
        {
            foreach (FileInfo file in directoryPath.GetFiles())
            {
                var path = directoryPath.FullName;
                string zipPath = path + file.Name;
                string extractPath = Regex.Replace(path + file.Name, ".zip", "");

                ZipFile.ExtractToDirectory(zipPath, extractPath);
            }
        }


    }
}

ويمكنك أن تفعل كل شيء في .NET Framework 3.5 باستخدام DeflateStream. الشيء تفتقر إلى .NET Framework 3.5 هو القدرة على معالجة مقاطع رأس الملفات التي تستخدم لتنظيم ملفات مضغوطة. وقد نشرت PKWare هذه المعلومات، والتي يمكنك استخدامها لمعالجة ملف مضغوط بعد إنشاء الهياكل التي يتم استخدامها. انها ليست مرهقة بشكل خاص، وممارسة جيدة في أداة البناء دون استخدام كود 3rd الطرف.

وليس من إجابة سطر واحد، ولكنها قابلة للتنفيذ تماما إذا كنت مستعدة وقادرة على أخذ الوقت لنفسك. كتبت فئة للقيام بذلك في بضع ساعات وما حصلت عليه من هذا هو القدرة على الرمز البريدي وبفك الملفات باستخدام .NET Framework 3.5 فقط.

وهذا سوف نفعل ذلك System.IO.Compression.ZipFile.ExtractToDirectory(ZipName, ExtractToPath)

واكتشفت عن هذا واحد (حزمة بفك في NuGet) اليوم، لأنني واجهت الصعب خطأ في DotNetZip، وأنا أدرك لم يكن هناك حقا أن الكثير من العمل المنجز على DotNetZip على مدى العامين الماضيين.

وحزمة بفك هي العجاف، وفعلت المهمة بالنسبة لي - لم يكن لديها الخلل الذي كان DotNetZip. أيضا، كان ملف صغير إلى حد معقول، والاعتماد على مايكروسوفت BCL لتخفيف الضغط الفعلي. أنا يمكن بسهولة جعل التعديلات التي كنت بحاجة (لتكون قادرة على تتبع التقدم حين فك الضغط). أنا أوصي به.

ومن تضمين RESSOURCES:

using (Stream _pluginZipResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(programName + "." + "filename.zip"))
{
    using (ZipArchive zip = new ZipArchive(_pluginZipResourceStream))
    {
        zip.ExtractToDirectory(Application.StartupPath);
    }
}

وحتى الآن، كنت تستخدم عمليات كمد من أجل استخراج ملف ايزو، بنسخه إلى مسار مؤقت من الخادم واستخراجها على عصا. مؤخرا لقد وجدت أن هذا يعمل تماما مع وايزو التي هي أقل من 10GB. لايزو مثل 29Gb يحصل عالقا هذه الطريقة بطريقة أو بأخرى.

    public void ExtractArchive()
    {
        try
        {

            try
            {
                Directory.Delete(copyISOLocation.OutputPath, true); 
            }
            catch (Exception e) when (e is IOException || e is UnauthorizedAccessException)
            {
            }

            Process cmd = new Process();
            cmd.StartInfo.FileName = "cmd.exe";
            cmd.StartInfo.RedirectStandardInput = true;
            cmd.StartInfo.RedirectStandardOutput = true;
            cmd.StartInfo.CreateNoWindow = true;
            cmd.StartInfo.UseShellExecute = false;
            cmd.StartInfo.WindowStyle = ProcessWindowStyle.Normal;

            //stackoverflow
            cmd.StartInfo.Arguments = "-R";

            cmd.Disposed += (sender, args) => {
                Console.WriteLine("CMD Process disposed");
            };
            cmd.Exited += (sender, args) => {
                Console.WriteLine("CMD Process exited");
            };
            cmd.ErrorDataReceived += (sender, args) => {
                Console.WriteLine("CMD Process error data received");
                Console.WriteLine(args.Data);
            };
            cmd.OutputDataReceived += (sender, args) => {
                Console.WriteLine("CMD Process Output data received");
                Console.WriteLine(args.Data);
            };

            //stackoverflow


            cmd.Start();

            cmd.StandardInput.WriteLine("C:");
            //Console.WriteLine(cmd.StandardOutput.Read());
            cmd.StandardInput.Flush();

            cmd.StandardInput.WriteLine("cd C:\\\"Program Files (x86)\"\\7-Zip\\");
            //Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            cmd.StandardInput.Flush();

            cmd.StandardInput.WriteLine(string.Format("7z.exe x -o{0} {1}", copyISOLocation.OutputPath, copyISOLocation.TempIsoPath));
            //Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            cmd.StandardInput.Flush();
            cmd.StandardInput.Close();
            cmd.WaitForExit();
            Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            Console.WriteLine(cmd.StandardError.ReadToEnd());

يمكنك استخدام معلومات فك الضغط سطر الأوامر cod. ما عليك سوى تنزيل unzip.exe من موقع Info-unzip الرسمي.

 internal static void Unzip(string sorcefile)
    {
        try
        {
            AFolderFiles.AFolderFilesDelete.DeleteFolder(TempBackupFolder); // delete old folder   
            AFolderFiles.AFolderFilesCreate.CreateIfNotExist(TempBackupFolder); // delete old folder   
           //need to Command command also to export attributes to a excel file
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; // window type
            startInfo.FileName = UnzipExe;
            startInfo.Arguments = sorcefile + " -d " + TempBackupFolder;
            process.StartInfo = startInfo;
            process.Start();
            //string result = process.StandardOutput.ReadToEnd();
            process.WaitForExit();
            process.Dispose();
            process.Close();
        }
        catch (Exception ex){ throw ex; }
    }        
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top