|
|
Title | Use the System.IO.Compression namespace to compress and decompress files in GZip format in Visual Basic 2005 |
Description | This example shows how to use the System.IO.Compression namespace to compress and decompress files in GZip format in Visual Basic 2005. |
Keywords | compress, decompress, compression, GZip, Visual Basic 2005 |
Categories | Algorithms, Miscellany, Files and Directories |
|
|
This example uses the System.IO.Compression namespace to compress and decompress files using the GZip format.
When you click the Go button, the program executes the following code. It compresses a file, decompresses it, and then compares the original file with the decompressed version.
|
|
Private Sub btnGo_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnGo.Click
' Compress.
GZipFile(txtOriginalFile.Text, txtCompressedFile.Text)
' Decompress.
GUnzipFile(txtCompressedFile.Text, _
txtDecompressedFile.Text)
' Compare with the original.
CompareFiles(txtOriginalFile.Text, _
txtDecompressedFile.Text)
End Sub
|
|
The program uses the GZipStream class to compress and decompress files. Unfortunately this class and its methods are not very symmetric and don't reallky seem to work well with streams in general so using them requires two fairly different subroutines and intermediate buffers.
Subroutine GZipFile uses a FileStream to read the input file into a byte array. It then opens a FileStream to write the compressed file and uses it to create a GZipStream object for compression. It writes the buffer into the GZipStream and closes the streams.
|
|
' Compress a file.
Private Sub GZipFile(ByVal from_file As String, ByVal _
to_file As String)
Dim num_bytes As Long
Dim buf() As Byte
' Read the input file into a buffer.
Using from_stream As New FileStream(from_file, _
FileMode.Open, FileAccess.Read, FileShare.Read)
num_bytes = from_stream.Length
ReDim buf(num_bytes - 1)
from_stream.Read(buf, 0, num_bytes)
from_stream.Close()
End Using ' from_stream
' Write the buffer to the output file.
Using to_stream As New FileStream(to_file, _
FileMode.Create, FileAccess.Write, FileShare.Write)
Using zip_stream As New GZipStream(to_stream, _
CompressionMode.Compress)
zip_stream.Write(buf, 0, num_bytes)
zip_stream.Close()
End Using ' zip_stream
to_stream.Close()
End Using ' to_stream
End Sub
|
|
Subroutine GUnzipFile opens a FileStream to read from a compressed file and uses it to create a GZipStream object for decompression. It then reads decompressed chunks of data from the GZipStream until it reaches the end of the file. (It would be nice if GZipStream could do this all at once or if it would at least tell you how big the decompressed file was so you could size the buffer at the beginning but it doesn't seem to provide those features.)
The routine then creates an output FileStream and writes the buffer's data into it.
|
|
' Decompress a file.
Private Sub GUnzipFile(ByVal from_file As String, ByVal _
to_file As String)
Dim buf() As Byte
' Read the input file into a buffer.
Using from_stream As New FileStream(from_file, _
FileMode.Open, FileAccess.Read, FileShare.Read)
Using zip_stream As New GZipStream(from_stream, _
CompressionMode.Decompress)
Const CHUNK As Integer = 1024
Dim total_bytes_read As Integer = 0
Do
' Enlarge the buffer.
ReDim Preserve buf(total_bytes_read + CHUNK _
- 1)
' Read the next chunk.
Dim bytes_read As Integer = _
zip_stream.Read(buf, total_bytes_read, _
CHUNK)
total_bytes_read += bytes_read
' See if we're done.
If bytes_read < CHUNK Then
' We're done. Make the buffer fit the
' data.
ReDim Preserve buf(total_bytes_read - 1)
Exit Do
End If
Loop
zip_stream.Close()
End Using ' zip_stream
from_stream.Close()
End Using ' from_stream
' Write the buffer into the output file.
Using to_stream As New FileStream(to_file, _
FileMode.Create, FileAccess.Write, FileShare.Write)
to_stream.Write(buf, 0, buf.Length)
to_stream.Close()
End Using ' to_stream
End Sub
|
|
Subroutine CompareFiles compares two files. It reads each file into a byte array, compares the arrays' lengths, and then compares the arrays byte-by-byte to see if they are the same.
|
|
' Compare two files.
Private Sub CompareFiles(ByVal filename1 As String, ByVal _
filename2 As String)
Dim file1() As Byte = _
My.Computer.FileSystem.ReadAllBytes(filename1)
Dim file2() As Byte = _
My.Computer.FileSystem.ReadAllBytes(filename2)
Dim files_different As Boolean = False
If file1.Length <> file2.Length Then
files_different = True
Else
For i As Integer = 0 To file1.Length - 1
If file1(i) <> file2(i) Then
files_different = True
Exit For
End If
Next i
End If
If files_different Then
MessageBox.Show("The files are different", "Error", _
MessageBoxButtons.OK, _
MessageBoxIcon.Information)
Else
MessageBox.Show("The files are identical", _
"Success", MessageBoxButtons.OK, _
MessageBoxIcon.Information)
End If
End Sub
|
|
|
|
|
|