Implementing File Compression and Encryption in Visual Basic 6 Using the Microsoft .NET Framework, Part II: Compression
Swigart Consulting LLC.
Microsoft Visual Basic 6
Microsoft Visual Basic .NET 2003
Microsoft Visual Basic 2005
Microsoft Visual Studio .NET 2003
Microsoft Visual Studio 2005
Summary: In this two-part article series, you'll see how you can easily add encryption and data compression (ZIP) capabilities to existing Visual Basic 6 applications using the .NET Framework. While encryption and compression may not seem like related technologies, if you think about it, each one takes a set of data and performs a transformation on it. In the case of encryption, the data is made unreadable, and with compression, the data is made smaller. You'll also see that both utilize many of the same underlying technologies. (8 printed pages)
Click here to download the code sample for this article.
So far, in the Visual Basic Fusion article series, you've been exposed to a significant amount of functionality provided by the Microsoft .NET Framework, but you should also know that there is an enormous amount of high quality open-source code that is also easy to use from your Visual Basic 6 applications. By creating very lightweight wrappers, you can expose functionality in open-source and third party libraries—originally developed for use in .NET applications—to extend your Visual Basic 6 applications. Sites like www.sourceforge.net and www.gotdotnet.com contain literally thousands of open-source projects, providing an extremely broad range of additional functionality. Just a few examples include libraries for RS232 (serial port) communication, working with RSS feeds, working with images and media files, network libraries, FTP libraries, file replication, and thousands of other libraries.
This article will look at utilizing one such open-source library for file compression. SharpZipLib is an open-source project that provides compression (ZIP) functionality. Version 2.0 of the .NET Framework also contains some support for file compression, but SharpZipLib affords more compression options, and makes it easier to create zip archives of whole folders. You can freely include this library even in close-source, for-sale software if you desire.
Before digging into the details of using SharpZipLib, it's worth comparing how .NET file I/O differs from Visual Basic 6 file I/O. As a quick review, Visual Basic 6 uses keywords to control file input and output.
Example 1. Reading for a file with Visual Basic 6
Dim dataIn As String Open someFileName For Input As #1 Do Until Eof(1) Line Input #1, dataIn Debug.Print dataIn Loop Close #1
In Visual Basic .NET, you would instead use some specific classes in the .NET Framework to perform File I/O operations.
Example 2. Visual Basic .NET File IO
Dim dataIn As String Dim sw As New StreamWriter("C:\log.txt") sw.WriteLine("This is a test") sw.Close()
With Visual Basic 6, you have to manage file handles, and you have to know the associated language keywords needed to work with that file handle. With Visual Basic .NET, the StreamWriter class wraps up all the functionality associated with files. You don't need to manage the file handles, and the file operations are more discoverable, because you have IntelliSense that will show you all the operations (WriteLine and others) available when working with files.
But the real advantage of these objects (also known as streams) is that they let you stack file I/O functionality. In the first article, you saw how encryption was supported by just adding a CryptoStream to the stack of I/O streams.
Example 3. Stacking streams to enable encryption with Visual Basic .NET
fs = New FileStream(fileName, FileMode.Create, FileAccess.Write) cs = New CryptoStream(fs, rc2.CreateEncryptor(), CryptoStreamMode.Write) sw = New StreamWriter(cs)
So anything written to the StreamWriter is then sent through the CyrptoStream, where it is encrypted, and then sent to the FileStream where it is written to disk.
Compression works exactly the same way.
Example 4. Stacking streams to enable compression with Visual Basic .NET
Dim fs = New FileStream(fileName, FileMode.Create, FileAccess.Write) zs = New GZipOutputStream(fs) sw = New StreamWriter(zs)
As you can see, compression composes with File IO exactly the same way as encryption, which makes sense. Both encryption and compression are really just a transformation of the data. With encryption, the data is transformed to a format that's not readable without a key. With compression, the data is transformed so that it requires fewer bytes to represent the same data.
The entire .NET class that enables you to write out information to a compressed file is as follows.
Example 5. Entire Visual Basic .NET class needed to allow you to write to a compressed file
Public Class GZipFileWriterWrapper Private fs As FileStream Private zs As GZipOutputStream Private sw As StreamWriter Public Sub Open(ByVal fileName As String) fs = New FileStream(fileName, FileMode.Create, FileAccess.Write) zs = New GZipOutputStream(fs) sw = New StreamWriter(zs) End Sub Public Sub WriteLine(ByVal value As String) sw.WriteLine(value) End Sub Public Sub Write(ByVal value As String) sw.Write(value) End Sub Public Sub WriteBytes(ByRef bytes() As Byte) zs.Write(bytes, 0, bytes.Length) End Sub Public Sub Close() On Error Resume Next If Not sw Is Nothing Then sw.Close() If Not zs Is Nothing Then zs.Close() If Not fs Is Nothing Then fs.Close() End Sub End Class
Now it's time to use this from a Visual Basic 6 application, to write information out to a compressed file. With this wrapper in place, the Visual Basic 6 code is trivial.
Example 6. Visual Basic 6 code to write to a compressed file
Dim e As wrappers.GZipFileWriterWrapper Set e = New wrappers.GZipFileWriterWrapper e.Open "c:\file.gzip" e.WriteLine (txtMessage) e.Close txtMessage = "" MsgBox "Compressed and Saved"
You can see that you simply use the wrapper to open the file, write as much as you want to it, and then close it when you're done. If you try to just open the disk file with something like Notepad, you can see that it has been written in a binary compressed format.
Figure 1. Examining the compressed file
However, using a Visual Basic 6 application, you can easily use the wrapper to read the compressed information back in.
Example 7. Reading the compressed file with Visual Basic 6
e.Open "c:\file.gzip" While Not e.EOF txtMessage = txtMessage & e.ReadLine & vbCrLf ' Could also just use e.ReadToEnd to read ' the entire file. Wend e.Close
The kind of compression shown so far lets you compress information before placing it into a file. However, it's common to want to create a zip archive, where you have a zip file that contains one or more disk files. This functionality is provided with the following wrapper around the SharpZipLib.
Example 8. Visual Basic .NET wrapper to create a Zip archive
Public Sub ZipFile(ByVal source As String, ByVal dest As String) Dim entry As New ZipEntry(Path.GetFileName(source)) Dim fi As New FileInfo(source) entry.ExternalFileAttributes = fi.Attributes entry.Size = fi.Length Dim input As FileStream = File.OpenRead(source) Dim output As New ZipOutputStream(File.Create(dest)) output.PutNextEntry(entry) Dim buffer(8191) As Byte Dim len As Integer Do len = input.Read(buffer, 0, buffer.Length) If len > 0 Then output.Write(buffer, 0, len) End If Loop Until len = 0 output.Close() input.Close() End Sub
Here, the ZipEntry class is used to write information about the file that will be added to the archive. Once the ZipEntry is written to the ZipOutputStream, the actual file contents are written. The result is a zip archive that can be opened using WinZip, or the zip functionality built into Windows XP. Now that the wrapper is built, zipping a file from Visual Basic 6 is as simple as the following.
Example 9. Zipping a file from Visual Basic 6
CommonDialog1.ShowOpen Dim source As String source = CommonDialog1.FileName Dim e As wrappers.FileZipWrapper Set e = New wrappers.FileZipWrapper e.ZipFile source, source & ".zip"
This prompts the user for a file to zip, and then uses the wrapper to zip the file. The result is a zip archive that is readable by Windows XP or other zip readers.
Figure 2. Zipping a single file
Finally, you may want to zip an entire folder, and a wrapper is provided for that, as well.
Example 10. Visual Basic 6 code to zip and entire folder structure
Dim e As wrappers.FileZipWrapper Set e = New wrappers.FileZipWrapper e.ZipFolder App.Path, App.Path & "\..\file.zip"
In part I of this article series, we created a sample that would let you exercise the encryption functionality. I've modified that sample to instead use the compression wrappers provided here. To use the sample:
- Download and install the .NET Framework 2.0 Software Development Kit (if you have Visual Studio .NET 2005 or Visual Basic Express installed, you can skip this step).
- Download the code associated with this article.
- Execute the "Install.bat" file included with the code for this article. This registers the encryption component so that you can use it from your Visual Basic 6 application.
- In the code for this article, open the Visual Basic 6 project in the "Compression" folder.
- Press F5 to run the sample application:
Figure 3. Form 1
- When you click Compress, the text in the textbox will be written to a file using the GZip compression algorithm. When you click Decompress, the contents will be decrypted and displayed.
- Clicking Zip File will prompt you to choose a file, and will create a zip archive that contains the file. Clicking Unzip will extract the file from the archive.
- Finally, Clicking Zip Folder will compress the contents of an entire folder.
To use this functionality from your own application, just run "Install.bat" and then add a reference to "wrappers.dll."
The Microsoft .NET Framework includes extensive functionality for many scenarios, but the open-source community has contributed a staggering amount of additional functionality that can be wrapped and used just as easily from Visual Basic 6. To some degree, this is nothing new. Visual Basic 6 has always enjoyed a large community that has been generous about providing code samples. Sometimes these have been snippets, and sometimes they have been full libraries. However, with Visual Basic 6, you were limited to code developed and shared by other Visual Basic 6 developers. With .NET, both Visual Basic .NET and C# developers can contribute code that your application can use (SharpZipLib was written in C#, but that doesn't make it any more difficult to wrap and use from Visual Basic 6 than if it was written in Visual Basic .NET). In addition, a tremendous number of libraries originally written in C++ and Java have been ported to .NET. This means that you have, at your disposal, thousands of additional libraries, many ported from libraries that have been developed, enhanced, and used in production applications for many years.
As the VB Fusion article series has shown, you can leverage everything that .NET provides while preserving your existing investment in Visual Basic 6 code. As this article specifically has shown, you're by no means limited to just the .NET framework and libraries provided by Microsoft. The thriving .NET community is at your disposal.
About the author
Scott Swigart (www.swigartconsulting.net) spends his time consulting, authoring, and speaking about emerging and converging technologies. Scott has worked with a wide range of technologies over his career, beginning with Commodore 64 programming at the age of 12, writing hardware diagnostics for UNIX systems in C++, and building windows desktop, and Web applications. Over the years, Scott has worked with component development, XML technologies, .NET, Web service, and other languages, platforms, and paradigms. With this experience, Scott has seen how technology evolves over time, and is focused on helping organizations get the most out of the technology of today, while preparing for the technology of tomorrow. Scott is also a Microsoft MVP, and co-author of numerous books and articles. Scott can be reached at Scott Swigart.