What is the "best" way to compress FileStream?

JumpyNET

Well-known member
Joined
Apr 4, 2005
Messages
151
I tried using "System.IO.Compression" to compress a stream I am saving to harddisk. It reduced the file size a bit, but when I recompressed the files again with an arhiving software the results amazed me. The uncompressed files squeezed in to much smaller files.

Here are the file sizes:
Uncompressed 256 KB
Uncompressed --> rar --> 64 KB
Uncompressed --> zip --> 75 KB
GZipStreamed 197 KB
GZipStreamed --> rar --> 107 KB
GZipStreamed --> zip --> 110 KB

What do you suggest? Should I save the files uncompressed and compress the files with some algorithm? Or do you know a better way to compress a FileStream?


Here is the code I am using:
[VB]
Public Sub SaveAllFunctionsToFile(ByVal SavePath As String, Optional ByVal Compress As Boolean = False)

Select Case Compress
Case True
Dim fs As New System.IO.FileStream(SavePath, IO.FileMode.Create)
Dim s As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim Compresser As New System.IO.Compression.GZipStream(fs, IO.Compression.CompressionMode.Compress, False)
s.Serialize(Compresser, AllFunctions)
Compresser.Close()
fs.Close()
Case False
Dim fs As New System.IO.FileStream(SavePath, IO.FileMode.Create)
Dim s As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
s.Serialize(fs, AllFunctions)
fs.Close()
End Select

End Sub
[/VB]


PS: I am using VB 2005 Express.
 
Looking at the classes under the System.IO.Compression namespace and as far as I can see neither the Defalte or the GZip streams give any means to set the compression level.

http://www.icsharpcode.net/OpenSource/SharpZipLib/Default.aspx provide a free compression library that does expose the compression level however and is just as easy to use...

e.g. the following is a simple cut and paste of the same routine
Code:
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim st As String
        Dim sr As New System.IO.StreamReader("c:\setupapi.log.0.old")

        st = sr.ReadToEnd()

        Dim fs As New System.IO.FileStream("c:\test1.bin", IO.FileMode.Create)
        Dim s As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
        Dim Compresser As New System.IO.Compression.GZipStream(fs, IO.Compression.CompressionMode.Compress, False)
        s.Serialize(Compresser, st)
        Compresser.Close()
        fs.Close()

    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim st As String
        Dim sr As New System.IO.StreamReader("c:\setupapi.log.0.old")

        st = sr.ReadToEnd()

        Dim fs As New System.IO.FileStream("c:\test2.bin", IO.FileMode.Create)
        Dim s As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter

        Dim Compresser As New ICSharpCode.SharpZipLib.GZip.GZipOutputStream(fs)
        Compresser.SetLevel(9)
        s.Serialize(Compresser, st)
        Compresser.Close()
        fs.Close()
    End Sub

the c:\setupapi.log.0.old file is a 4.5M text file found in my windows folder which using the built in GZip compressed to 590K, using the ICSharp library set to level 9 compression came out as 155K - a fairly impressive saving.

Given the ease of use of the ICSharp library I would be tempted to go that route rather than saving an uncompressed stream and then using some other tool to compress it later.

As an aside the file sizes you were getting are reflective of the fact that an uncompressed file has more redundancy than a partially compressed file and can be compressed better.

EDIT: just tried it with the ICSharps BZip2 routine
Code:
Dim Compresser As New ICSharpCode.SharpZipLib.BZip2.BZip2OutputStream(fs)

and the resultant file is now only 124K
 
Thanks. That sure seems easy. The CSharp in the librarys name scared me of before. It is good to know that SharpZipLib works also in VB.
 
Back
Top