Kompresja strumieni
Od wersji .NET 2.0 zostały udostępnione nam strumienie kompresujące. Znajdują się one w przestrzeni nazw:
Są to:
Przy czym musimy pamiętać, ze do kompresji i dekompresji musimy używać tego samego strumienia.
Mimo że GZip korysta z algorytmu Deflate, to GZipStream dodaje do plików róznego rodzaju nagłówki, dzięki czemu będziemy mogli uruchomić skompresowane pliki np. w WinZIPie.
Natomiast DeflateStream stosuję czystą kompresję, przez co nie uruchomimy tak skompresowanego pliku w większości archiwizerów.
Więc jeśli kompresować i dekompresować będziemy wyłącznie w naszym programie możemy spokojnie użyć DeflateStream.
CompressionMode służy do ustawienia, czy mamy kompresować czy dekompresować dane:
Aby użyć kompresji, należy strumień kompresujący przekierować na inny strumień np. FileStream.
Przykład 1:
Metoda z przykładu 1. kompresuje tablicę byte'ów buf i zapisuje do pliku skompresowaną.
A co jeśli chcemy skompresować coś innego, np. tekst?
Musimy stworzyć następny strumień np. StreamWriter, który będzie przekierowywany na strumień kompresji, a ten z kolei do pliku ;-)
Przykład 2:
Tym samym sposobem możemy skompresować cały plik. Wystarczy stworzyć kolejny strumień pliku:
Następnie kopiujemy dane ze strumienia fsInput do strumienia kompresji gZip.
Dekompresja strumieni jest analogiczna do kompresji:
Przykład 3:
Przykłady, które przedstawiłem nie są zabezpieczone przed ewentualnymi błędami np. gdy plik nie istnieje. Przykłady miały pokazać jedynie główny sens korzystania ze strumieni kompresujących.
using System.IO.Compression;
Są to:
- DeflateStream
- GZipStream
Przy czym musimy pamiętać, ze do kompresji i dekompresji musimy używać tego samego strumienia.
Mimo że GZip korysta z algorytmu Deflate, to GZipStream dodaje do plików róznego rodzaju nagłówki, dzięki czemu będziemy mogli uruchomić skompresowane pliki np. w WinZIPie.
Natomiast DeflateStream stosuję czystą kompresję, przez co nie uruchomimy tak skompresowanego pliku w większości archiwizerów.
Więc jeśli kompresować i dekompresować będziemy wyłącznie w naszym programie możemy spokojnie użyć DeflateStream.
DeflateStream compressionStream = new DeflateStream(outputStream, CompressionMode.Compress);
CompressionMode służy do ustawienia, czy mamy kompresować czy dekompresować dane:
- CompressionMode.Compress - kompresja
- CompressionMode.Decompress - dekompresja
Aby użyć kompresji, należy strumień kompresujący przekierować na inny strumień np. FileStream.
Przykład 1:
public void SaveToFile(string FileName) { FileStream fsOutput = new FileStream(FileName, FileMode.Create); GZipStream gZip = new GZipStream(fsOutput, CompressionMode.Compress); byte[] buf = { 10, 12, 40, 32, 17 }; //przykładowa tablica byte'ów gZip.Write(buf, 0, buf.Length); gZip.Close(); fsOutput.Close(); }
Metoda z przykładu 1. kompresuje tablicę byte'ów buf i zapisuje do pliku skompresowaną.
A co jeśli chcemy skompresować coś innego, np. tekst?
Musimy stworzyć następny strumień np. StreamWriter, który będzie przekierowywany na strumień kompresji, a ten z kolei do pliku ;-)
Przykład 2:
public void SaveToFile(string FileName) { FileStream fsOutput = new FileStream(FileName, FileMode.Create); GZipStream gZip = new GZipStream(fsOutput, CompressionMode.Compress); StreamWriter writer = new StreamWriter(gZip); writer.WriteLine("Ala ma kota."; writer.WriteLine("Kot ma buty :-)"); writer.Close(); gZip.Close(); fsOutput.Close(); }
Tym samym sposobem możemy skompresować cały plik. Wystarczy stworzyć kolejny strumień pliku:
FileStream fsInput = new FileStream(FileName, FileMode.Open);który będzie zawierał plik źródłowy.
Następnie kopiujemy dane ze strumienia fsInput do strumienia kompresji gZip.
Dekompresja strumieni jest analogiczna do kompresji:
Przykład 3:
string tekst; public void LoadFromFile(string FileName) { FileStream fsInput = new FileStream(FileName, FileMode.Open); GZipStream gZip = new GZipStream(fsInput, CompressionMode.Decompress); StreamReader reader = new StreamReader(gZip); tekst = reader.ReadLine(); reader.Close(); gZip.Close(); fsInput.Close(); }
Przykłady, które przedstawiłem nie są zabezpieczone przed ewentualnymi błędami np. gdy plik nie istnieje. Przykłady miały pokazać jedynie główny sens korzystania ze strumieni kompresujących.
Kategoria: C#
ogólnie nie jestem pewien, czy musze zamykać wszystkie strumienie pokolei.
Prawdopodomnie wystarczy zamknąć podstawowy strumień. Z takim czymś się spotkałem.
Czyli zamiast:
reader.Close();
gZip.Close();
fsInput.Close();
wystarczy:
fsInput.Close();