Aug 05 2010
Deflate Stream – Compress & Decompress
Merhaba, üzerinde çalışmakta olduğum projede bugun yapmış olduğum bir işlemin kodlarını sizinle paylaşmak istiyorum. Senaryo aslında çok derin, ama ben kısaca bahsedeyim. Kullanıcı bir Windows App yardımıyla SQL’e dosya yükler, veya bu dosyayı download eder. Tabi bu aşamada önemli olan şey içeriye yüklenen verinin boyutunun yüksek olabileceğinden dolayı bu dosyanın içeriğini sıkıştırarark yüklemektir. Veriyi database’de tutacagımız alan BINARY tipindedir. Buyrun kodlar.
Dosyayı OpenFileDialog ile kullanıcıdan seçtiriyorum, ve seçilen dosyanın path’ini aşağıdaki function’a gönderiyorum.
1: public byte[] FileToByteArray(string filePath)
2: {
3: FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
4: BinaryReader br = new BinaryReader(fs);
5:
6: long totalBytes = new FileInfo(filePath).Length;
7:
8: byte[] buffer = br.ReadBytes(Convert.ToInt32(totalBytes));
9: bufferSize = totalBytes;
10:
11: fs.Close();
12: fs.Dispose();
13: br.Close();
14:
15: return Compress(buffer);
16: }
Bu function oluşturduğu byte[] değerlerini Compress isimli aşağıdaki fonksiyon gönderiyor.
1: public static byte[] Compress(byte[] data)
2: {
3: MemoryStream ms = new MemoryStream();
4: DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress);
5: ds.Write(data, 0, data.Length);
6: ds.Flush();
7: ds.Close();
8: return ms.ToArray();
9: }
Bir dosyayı alarak, sıkıştırdık ve DB’ye kayıt etmeye hazır hale getirdik.
Şimdide DB’deki dosyayı kullanıcının download etmesini sağlayacak kod bloğunu yazıyorum.
1: FolderBrowserDialog dialog = new FolderBrowserDialog();
2: dialog.ShowDialog(this);
3:
4: if (!string.IsNullOrEmpty(dialog.SelectedPath))
5: {
6: string file = String.Format("{0}\\{1}", dialog.SelectedPath, ocd.FILE_NAME);
7:
8: FileStream fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
9: BinaryWriter bw = new BinaryWriter(fs);
10:
11: bw.Write(Decompress(ocd.FILE_DATA.ToArray()).ToArray());
12: bw.Flush();
13:
14: bw.Close();
15: }
Burada 11. satırda çağırılan function’ın almış oldugu ocd.FILE_DATA, bizim SQL’de depolamış olduğumuz binary verisidir.
Gönderildiği Decompress fonksiyonunun içeriği aşağıdaki gibidir.
1: public byte[] Decompress(byte[] data)
2: {
3: const int BUFFER_SIZE = 256;
4: byte[] tempArray = new byte[BUFFER_SIZE];
5: List<byte[]> tempList = new List<byte[]>();
6: int count = 0, length = 0;
7:
8: MemoryStream ms = new MemoryStream(data);
9: DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress);
10:
11: while ((count = ds.Read(tempArray, 0, BUFFER_SIZE)) > 0)
12: {
13: if (count == BUFFER_SIZE)
14: {
15: tempList.Add(tempArray);
16: tempArray = new byte[BUFFER_SIZE];
17: }
18: else
19: {
20: byte[] temp = new byte[count];
21: Array.Copy(tempArray, 0, temp, 0, count);
22: tempList.Add(temp);
23: }
24: length += count;
25: }
26:
27: byte[] retVal = new byte[length];
28:
29: count = 0;
30: foreach (byte[] temp in tempList)
31: {
32: Array.Copy(temp, 0, retVal, count, temp.Length);
33: count += temp.Length;
34: }
35:
36: return retVal;
37: }
İşte bu kadar basit. Bu sistem sayesinde her türlü verinin içeriğini Compress ederek DB’de saklayabilirsiniz. Hatırladığım kadarıyla SQL’de binary field’ı max 2 GB’a kadar verı tutabiliyor. 4 GB’da olabilir tabi