فشرده کردن و از حالت فشرده در آوردن یک فایل متنی

بهترین ایده برای فایلهایی که حجم انها زیاد شده است این است که آنها را فشرده کنیم. فشرده سازی پروسه کاهش حجم یک فایل است. این فرایند شامل یافتن ورودی های زائد و تکرار شده در یک فایل و تبدیل آنها به یک ورودی ساده است(یعنی اگر در یک فایل مثلا 100 بار کلمه Hello به کار رفته باشد آنها را به یک کلمه Hello در نظر می گیرد. ). کاهش حجم فایل ها در وب بیشتر کاربرد دارد. می توان با کاهش حجم صفحات وب سرعت بارگذاری یک وب سایت را بالا برد. از این فرایند همچنین می توان برای گرفتن پشتیبان یا بایگانی فایلها و نیز به اشتراک گذاشتن یک فایل در اینترنت (حجم فایل را کم کرده تا سریعتر آپلود و دانلود شود) استفاده نمود. از نرم افزارهای مختلفی مانند WinRar و WinZip می توان برای فشرده سازی استفاده نمود. اگر با فایلهایی که دارای پسوند .zip و .rar هستند مواجه شدید بدانید که این فایلها فشرده شده اند و حجم آنها در مقایسه با حالت عادی شان (غیر فشرده شان) کمتر است.

 

فشرده سازی فایلها با استفاده از کلاس های GzipStream و DeflateStream

کتابخانه کلاس دات نت دارای کلاس ها و متدهایی جهت فشرده سازی و باز کردن فایل ها از حالت فشرده می باشد. این کلاس ها از الگوریتم GZIP یا Deflate جهت فشرده سازی فایلها استفاده می کنند. در این درس می خواهیم یک فایل متنی را به راحتی فشرده کنیم. شما می توانید برای فشرده کردن فایلها و باز کردن فایها از حالت فشرده از کلاس GzipStream یا DeflateStream استفاده کنید. کارکرد این دو کلاس تقریبا شبیه هم است.این کلاس ها به یک شی از FileStream که به یک فایل اشاره می کند، نیاز دارند. اجازه بدهید که نحوه استفاده به موقع از این کلاس ها را توضیح دهیم. در زیر دو مجموعه کد مربوط به دو کلاس ذکر شده است. یک برنامه کنسول با نام TextFileCompression ایجاد کنید. دو فضای نام لازم برای برنامه مان را وارد نمایید.

using System.IO;
using System.IO.Compression;

ابتدا حجم یک فایل را در حالت فشرده و غیر فشرده مقایسه می کنیم. کد زیر را برای ایجاد یک فایل متنی بدون هیچ فشردگی می نویسیم:

   1: static void Main(string[] args)
   2: {
   3:     StringBuilder data = new StringBuilder();
   4: 
   5:     for (int i = 0; i < 1000; i++)
   6:     {
   7:         data.AppendLine("The quick brown fox jumps over the lazy dog.");
   8:     }
   9: 
  10:     Console.WriteLine("A compressed file was created!");
  11: 
  12:     try
  13:     {
  14:         FileStream stream = new FileStream(@"C:compressedFile.txt",
  15:             FileMode.Create, FileAccess.Write);
  16: 
  17:         StreamWriter writer = new StreamWriter(stream);
  18: 
  19:         writer.Write(data.ToString());
  20:         writer.Close();
  21:     }
  22:     catch (IOException ex)
  23:     {
  24:         Console.WriteLine(ex.Message);
  25:     }
  26: }

خطوط 8-3 ، 1000 خط ساختگی را در داخل فایل متنی می نویسد. خطوط 12 تا 25 یک فایل متنی را همانطور که در درس های قبلی یاد گرفتیم ایجاد می کنند. توجه کنید که ما تا الان هیچ عملی جهت فشرده کردن فایل انجام نداده ایم. همانطور که در خط 14 مشاهده می کنید یک فایل متنی در C:compressedFile.txt ایجاد می شود. اگر به مسیر بالا رفته و حجم فایل مورد نظر را چک کنید مشاهده می کنید که حجم آن در حدود 45 کیلو بایت است. حال اجازه بدهید که از کلاس های فضای نام System.IO.Compression جهت فشرده سازی استفاده کنیم. در مثال زیر از GzipStream و در مثال بعد از DeflateStream جهت فشرده سازی فایل مذکور استفاده می کنیم :

   1: static void Main(string[] args)
   2: {
   3:     StringBuilder data = new StringBuilder();
   4: 
   5:     for (int i = 0; i < 1000; i++)
   6:     {
   7:         data.AppendLine("The quick brown fox jumps over the lazy dog.");
   8:     }
   9: 
  10:     Console.WriteLine("A compressed file was created!");
  11: 
  12:     try
  13:     {
  14:         FileStream stream = new FileStream(@"C:compressedFile.txt",
  15:             FileMode.Create, FileAccess.Write);
  16: 
  17:         GZipStream gzip = new GZipStream(stream, CompressionMode.Compress);
  18: 
  19:         StreamWriter writer = new StreamWriter(gzip);
  20: 
  21:         writer.Write(data.ToString());
  22:         writer.Close();
  23:     }
  24:     catch (IOException ex)
  25:     {
  26:         Console.WriteLine(ex.Message);
  27:     }
  28: }

این مثال تقریبا شبیه به مثال صفحه قبل است و تفاوت آنها در خطوط 17 و 19 می باشد. در خط 17 شی GzipStream از الگوریتم GZIP جهت فشرده سازی استفاده می کند. در داخل سازنده (خط 17)، شی ایجاد شده از FileStream یعنی straem را قرار می دهیم. دومین پارامتر سازنده یک مقدار از نوع شمارشی CompressionMode است که شامل دو مقدار Compress و Decompress می باشد. برای ایجاد فایل های فشرده از مقدار CompressionMode.Compress استفاده می کنیم. در خط 19 به جای ارسال FileStream به StreamWriter، شی ایجاد شده GzipStream را ارسال می کنیم. وقتی که متد Write() در خط 21 را فراخوانی می کنیم، داده های نوشته شده به طور خودکار با استفاده از الگوریتم GZIP فشرده می شوند. به یاد دارید که حجم فایل در حالت غیر فشرده در حدود 45kb بود. حال اجازه بدهید که نگاهی به سایز جدید فایل در حالت فشرده بیندازیم. مشاهده می کنید که حجم ان در این حالت 660 byte یا در حدود 1kb می باشد که 44KB کمتر از فایل غیر فشرده ای است که قبلا ایجاد کردیم.مقدار کاهش یک فایل به مقدار زوائد و کل سایز فایل بستگی دارد. از آنجاییکه فایل اصلی شامل یک جمله است که 1000 بار تکرار شده است کار فشرده سازی فایل راحت تر می شود.
اگر فایل متنی فشرده شده را باز کنید نمی توانید آن را بخوانید چون محتویات آن تغییر کرده است. همانطور که در مثال زیر مشاهده خواهید کرد کلاس DeflateStream بسیار شبیه به کلاس GzipStream می باشد. سایز فایل فشرده ایجاد شده توسط الگوریتم بالا در حدود 640bytes است که کمی کمتر از حالت فشرده آن به وسیله الگوریتم Gzip می باشد.

   1: static void Main(string[] args)
   2: {
   3:     StringBuilder data = new StringBuilder();
   4: 
   5:     for (int i = 0; i < 1000; i++)
   6:     {
   7:         data.AppendLine("The quick brown fox jumps over the lazy dog.");
   8:     }
   9: 
  10:     Console.WriteLine("A compressed file was created!");
  11: 
  12:     try
  13:     {
  14:         FileStream stream = new FileStream(@"C:compressedFile.txt",
  15:             FileMode.Create, FileAccess.Write);
  16: 
  17:         DeflateStream deflate = new DeflateStream(stream, CompressionMode.Compress);
  18: 
  19:         StreamWriter writer = new StreamWriter(deflate);
  20: 
  21:         writer.Write(data.ToString());
  22:         writer.Close();
  23:     }
  24:     catch (IOException ex)
  25:     {
  26:         Console.WriteLine(ex.Message);
  27:     }
  28: }

 

باز کردن فایل از حالت فشرده

برای خواندن فایل های فشرده باید آنها را باز کرد. برای این کار نیز می توان از کلاس های GzipStream و DeflateStream استفاده کرد. ابتدا نحوه استفاده از کلاس GzipStream برای باز کردن فایل ها از حالت فشرده را توضیح می دهیم. به این نکته توجه کنید که از یک کلاس صحیح برای باز کردن یک فایل فشرده استفاده کنید. مثلا اگر یک فایل با استفاده از Deflate فشرده شده است باید از DeflateStream برای باز کردن آن از حالت فشرده استفاده کنید تا با خطا مواجه نشوید.

   1: static void Main(string[] args)
   2: {
   3:     try
   4:     {
   5:         FileStream stream = new FileStream(@"C:compressedFile.txt",
   6:             FileMode.Open, FileAccess.Read);
   7: 
   8:         GZipStream gzip = new GZipStream(stream, CompressionMode.Decompress);
   9: 
  10:         StreamReader reader = new StreamReader(gzip);
  11:         string contents = reader.ReadToEnd();
  12:         reader.Close();
  13: 
  14:         Console.WriteLine(contents);
  15: 
  16:     }
  17:     catch (IOException ex)
  18:     {
  19:         Console.WriteLine(ex.Message);
  20:     }

مطمئن باشید که فایلی که شما دارید از حالت فشرده خارج می کنید اگر با کلاس GzipStream فشرده شده باشد و بخواهید آن را با استفاده از کلاس DeflateStream باز کنید با خطا مواجه می شوید. در خطوط 6-5 یک شی FileStream ایجاد شده است که به یک فایل فشرده اشاره می کند. برای خواندن محتویات فایل از مقادیر FileMode.Open و FileAccess.Readدر داخل سازنده استفاده می کنیم. در خط 8 یک شی از GzipStream ایجاد می کنیم. تنها تفاوت تعیین مقدار compression mode در آرگومان دوم است. در این خط (خط 8) مقدار CompressionMode.Decompress را قرار می دهیم. از این مقدار (decompress) برای باز کردن فایل فشرده استفاده می شود. شی GzipStream ایجاد شده از قبل را به شی StreamReader در خط 10 ارسال می کنیم تا محتویات فایل را بخواند. در خط 11 از متد ReadToEnd() استفاده شده ایت که محتویات فایل فشرده را باز کرده و آن را به عنوان یک رشته بر می گرداند. در خط 14 نیز محتویات فایل، که از حالت فشرده خارج شده اند نمایش داده می شوند. اگر فایل را با استفاده از کلاس DeflateStream فشرده کرده اید باید از همین کلاس هم برای باز کردن آن استفاده نمایید. در مثال زیر به شما نشان می دهیم که چگونه یک فایل را با استفاده از کلاس DeflateStream از حالت فشرده خارج کنیم. برای این کار، دقیقا مانند استفاده از کلاس GzipStream عمل می کنیم.

   1: static void Main(string[] args)
   2: {
   3:     try
   4:     {
   5:         FileStream stream = new FileStream(@"C:compressedFile.txt",
   6:             FileMode.Open, FileAccess.Read);
   7: 
   8:         DeflateStream deflate = new DeflateStream(stream, CompressionMode.Decompress);
   9: 
  10:         StreamReader reader = new StreamReader(deflate);
  11:         string contents = reader.ReadToEnd();
  12:         reader.Close();
  13: 
  14:         Console.WriteLine(contents);
  15: 
  16:     }
  17:     catch (IOException ex)
  18:     {
  19:         Console.WriteLine(ex.Message);
  20:     }

در این درس به شما نحوه فشرده کردن یک فایل ساده آموزش داده شد. شما می توانید از این کلاس ها برای فشرده سازی انواع مختلف فایل استفاده کنید.

لطفا اگر نظر، پیشنهاد و یا انتقادی در باره مطلب بالا دارید در قسمت زیر و اگر سوالی دارید در بخش پرسش و پاسخ مطرح بفرمایید.

  1. شایگان پاسخ دادن

    فایل های زیپ و rar رو چجوری میشه درست کرد اونا هم کلاس اماده دارن؟

  2. تکتم پاسخ دادن

    سلام
    خسته نباشید
    چطور میشه یک فایل RAR را با زبان C++ خوند؟
    لطفا کمک کنید