Hızlı Konu Açma

Hızlı Konu Açmak için tıklayınız.

Son Mesajlar

Konulardaki Son Mesajlar

Reklam

Forumda Reklam Vermek İçin Bize Ulaşın

GZip ile Sıkıştırma İşlemi

YaSa22

Fahri Üye
Fahri Üye
Katılım
12 Temmuz 2014
Mesajlar
2,293
Tepkime puanı
2
Puanları
0
Konum
GTA
Merhabalar, bu yazımda .Net Framework 2.0 ile beraber gelmiş olan GzipStream sınıfına kısaca değineceğim. gzip gnu’nun sıkıştırma programıdır. UNIX’te .gz, VMS’te -gz, MSDOS’da, OS/2’te .z uzantılı dosyalardır. (

Linkleri sadece kayıtlı üyeler görebilir. Linkleri görebilmek için Üye Girişi yapın veya ücretsiz olarak Kayıt Olun

) GZip ifadesi "Gnu Zip" kelimesinin kısaltılmışıdır. Gzip in temelinde ise deflate isimli sıkıştırma algoritması vardır.

Bu sınıf akım(diğer adıyla stream)ları sıkıştırmak ve sıkıştırılmış akışları geri açmak için metotlar ve özellikler sağlıyor. DeflateStream sınıfıyla beraber System.IO.Compression isim alanında bulunuyor.

GzipStream sınıfı System.IO isim alanında bulunan Stream sınıfından türetilmiştir, yani sınıfımızı :

public class GzipStream : Stream

şeklinde gösterebiliriz.

gzip veri formatımız DeflateStream sınıfıyla aynı algoritmayı kullanır fakat diğer sıkıştırma metotlarını kullanabilmek için türetme yapabiliriz. Fakat gzip algortimasını 4 GB’den büyük dosyalar için kullanamayız.

DeflateStream ve GzipStream sınıflarının sıkıştırma fonksiyonları stream açığa çıkarır. Veri byte byte okunur. MSDN’de belirtildiğine göre bu sınıflar sıkıştırılmamış dosyalar için en iyidir fakat veri kaynağı önceden sıkıştırıldıysa boyut daha da artabilir.

Eğer GzipStream sınıfından türetme yapmak isterseniz CanSeek ,CanWrite ve CanRead üyelerini override etmelisiniz.

GzipStream sınıfının 2 tane yapıcı metodu vardır.

1-) GzipStream (Stream , CompressionMode)

2-) GzipStream (Stream , CompressionMode , boolean )

Birinici yapıcı metotta belirtilen stream ve compressionmode a göre GzipStream nesnesi yaratılır. Burada CompressionMode bir enum sabitidir. Belirtilen streamin sıkıştırılacağını mı yoksa sıkıştırılmış streamin açılacağını mı belirtir. 2 değer alır. Birisi CompressionMode.Compress diğeri ise CompressionMode.Decompress’tir.

Msdn’den bu sınıfa ait tüm metotları inceleyebilirsiniz. Bu yazımda sadece kısaca read ve write metotlarından bahsedeceğim.

Read Metodu: public override int Read(byte[] dizi,int ofset,int adet )

Bu metot adet kadar decompressed(sıkıştırıldıktan sonra geri açılmış) byte’ı byte türden diziye atar.

Write Metodu:public override void write ( byte[] dizi,int ofset,int sayac)

Bu metot ise dizideki ofsetinci byte’dan başlayarak sayac kadar sıkıştırılmış byte’ı stream nesnesine yazar.

Şimdi bir örnekle fonksiyonların kullanım şeklini inceleyelim. Örneğimiz aşağıdaki gibi bir Windows uygulamasından oluşmaktadır.



private void button1_Click(object sender, EventArgs e)//Sıkıştır butonunun
{
string dosya="ilkdosya.doc";
if (File.Exists(dosya))
GZipTest.GZipCompress(dosya);
}

private void button2_Click(object sender, EventArgs e)
{
string dosya = "yenidosya.gz";
if (File.Exists(dosya))
GZipTest.GZipDecompress(dosya);
}


Sıkıştır butonuna tıklanınca ilkdosya.doc adındaki dosyayı sıkıştırır,sıkıştırılmış dosyaya yenidosya.gz adını verdim. Geri aç butonuna tıklayınca ise yenidosya.gz adındaki dosya geri açılır ve sondosya.doc isimli dosyaya geri açılmış içerik yazılır. Bu işlemler aşağıdaki GzipTest adındaki sınıftaki GzipCompress ve GZipDecompress metodları kullanılarak yapılıyor.

GZipTest Sınıfı :

public class GZipTest
{
public static int ReadAllBytesFromStream(Stream stream, byte[] buffer)
{
int offset = 0;
int totalCount = 0;
while (true)
{
int bytesRead = stream.Read(buffer, offset, 100);
if (bytesRead == 0)
{
break;
}
offset += bytesRead;
totalCount += bytesRead;
}
return totalCount;
}

public static void GZipCompress(string dosya_adi)
{
FileStream infile;
try
{
infile = new FileStream(dosya_adi, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] buffer = new byte[infile.Length];
int count = infile.Read(buffer, 0, buffer.Length);
if (count != buffer.Length)
{
infile.Close();
MessageBox.Show("Dosya okuma sırasında sorun oluştu. ");
return;
}
infile.Close();
FileStream fss = new FileStream("yenidosya.gz", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
GZipStream compressedzipStream = new GZipStream(fss, CompressionMode.Compress, true);
compressedzipStream.Write(buffer, 0, buffer.Length);
compressedzipStream.Close();
fss.Close();
}
catch (Exception e)
{
MessageBox.Show("Error occured. "+e.Message);
}
}

public static void GZipDecompress(string filename)
{
FileStream infile;
try
{
infile = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] buffer = new byte[infile.Length];
int count = infile.Read(buffer, 0, buffer.Length);
if (count != buffer.Length)
{
infile.Close();
Console.WriteLine("Test Failed: Unable to read data from file");
return;
}

infile.Close();
FileStream fss = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
GZipStream zipStream = new GZipStream(fss, CompressionMode.Decompress);
byte[] decompressedBuffer = new byte[40000];
zipStream.Read(decompressedBuffer,0,40000);
FileStream sonst = new FileStream("sondosya.doc", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
sonst.Write(decompressedBuffer, 0, 40000);
zipStream.Close();
}
catch (Exception e)
{
MessageBox.Show("Error occured. ");
}
}
}


GzipCompress altyordamında, ilk önce parametre olarak geçirilen dosya okunuyor ve dosyanın içeriği buffer adındaki byte türünden diziye atılıyor.

FileStream fss = new FileStream("yenidosya.gz", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
GZipStream compressedzipStream = new GZipStream(fss,CompressionMode.Compress, true);
compressedzipStream.Write(buffer, 0, buffer.Length);


Sonra yukarıdaki satırlarda compressedzipStream adında bir tane GZipStream nesnesi oluşturuluyor ,CompressionMode’u Compress olarak belirtilerek sıkıştırma işlemi yapılacağını belirtmiş oluyoruz ve ayrıca FileStream türündeki fss’yi ilk argüman olarak geçirdiğimize dikkat edin.

compressedzipStream.Write(buffer, 0, buffer.Length);

satırında ise bufferdaki bilgiler sıkıştırılarak streame yazılıyor yani sıkıştırılmış verileri fss adındaki stream nesnesi ile yenidosya.gz’ye yazmış olduk.

zipStream.Read(decompressedBuffer,0,40000);
FileStream sonst = new FileStream("sondosya.doc", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
sonst.Write(decompressedBuffer, 0, 40000);


Decompress metodunda ise bu sefer sıkıştırılmış olan streamden okuyacağımız için read metodunu kullanıyoruz ve sıkıştırılmış dosyanın içeriğini decompressedBuffer içine atıyoruz. Ordaki 40000 gibi rakamlar sizi şaşıtmasın. Sıkıştırılmış dosyanın açıldığında kaç byte olacağını bilemediğim için FileStream sınıfına ait yazma fonksiyonunda 3. parametre olarak, ilkdosya.doc adındaki dosyamın boyutuna yakın bir değer olarak ,40000 değerini verdim.
 

Users Who Are Viewing This Konu (Users: 0, Guests: 1)

Üst