当需要在网上传送数据的情况下压缩是极其有用的,特别是对于非常慢且代价昂贵的网络,例如GPRS连接。在这种情况中,使用压缩能够极大地缩小数据尺寸并且减少整个通讯耗费。Web Service是另一个领域-此时,使用压缩能提供巨大的优点,因为XML数据能被高度压缩。
由于.NET Compact Framework 2.0没有支持命名空间System.IO.Compression,所以在NETCF上开发压缩和解压缩功能并不是很方便。
我相信很多人都知道SharpDevelop,开发ShareDevelop的ic#code有另一个开源项目SharpZipLib for .NET。SharpZipLib用.NET实现了Zip/GZip/BZip2/Tar的算法,可以很方便的按我们的要求做文件进行压缩和解压缩,而且更重要的是它的开源性。SharpZipLib可以在http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx下载。
这段时间做的一个移动软件项目里正好涉及将用户数据进行压缩/解压缩的功能,找了一些这方面的资料,现在把在NETCF下实现压缩和解压的代码贴上来。
下面给出了实现文件压缩/解压缩的基于.NET Compact Framework的Windows窗体界面设计。
图1:压缩 图2:解压缩
在图1中,首先在“压缩目标路径”输入框中设定路径,然后在“压缩文件名”输入框中设置即将生成的压缩文件名。本例设置目标路径为/Program Files/createzipfile/,路径下的所有文件(包含隐藏文件),都将被压缩到/Program Files/createzipfile/MyZip.zip文件中。
“压缩目标路径”输入框命名为txtSourceDir,“压缩文件名”输入框命名为txtZipFileName,“压缩”按钮命名为btnZipIt,按钮点击事件中的代码如清单1所示。
清单1:“压缩”按钮点击事件
Private Sub btnZipIt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnZipIt.Click Dim astrFileNames() As String = Directory.GetFiles(txtSourceDir.Text) Dim objCrc32 As New Crc32() Dim strmZipOutputStream As ZipOutputStream
strmZipOutputStream = New ZipOutputStream(File.Create(txtZipFileName.Text)) strmZipOutputStream.SetLevel(6)
Dim strFile As String
For Each strFile In astrFileNames Dim strmFile As FileStream = File.OpenRead(strFile) Dim abyBuffer(strmFile.Length - 1) As Byte
strmFile.Read(abyBuffer, 0, abyBuffer.Length) Dim objZipEntry As ZipEntry = New ZipEntry(strFile)
objZipEntry.DateTime = DateTime.Now objZipEntry.Size = strmFile.Length strmFile.Close() objCrc32.Reset() objCrc32.Update(abyBuffer) objZipEntry.Crc = objCrc32.Value strmZipOutputStream.PutNextEntry(objZipEntry) strmZipOutputStream.Write(abyBuffer, 0, abyBuffer.Length) Next
strmZipOutputStream.Finish() strmZipOutputStream.Close()
MessageBox.Show("压缩完成") End Sub |
在图2中,首先在“压缩文件名”输入框中指定需要查看或解压缩的压缩文件名,点击“查看”按钮后将指定的压缩文件内的文件显示在ListView控件中,在ListView控件中选中一行记录并在弹出式菜单中选择“释出”菜单项将文件解压缩出来。本例设置压缩文件名为/Program Files/createzipfile/MyZip.zip。“压缩文件名”输入框命名为txtFileName,ListView控件命名为lvZipContents,“查看”按钮命名为btnView,按钮点击事件中的代码如清单2所示。“释出”菜单项点击事件中的代码如清单3所示。
清单2:“查看”按钮点击事件
Private Sub btnView_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnView.Click Dim objEntry As ZipEntry Dim dtStamp As DateTime Dim objItem As ListViewItem Dim zFile As ZipFile
Try zFile = New ZipFile(txtFileName.Text) Catch Ex As System.Exception MessageBox.Show(Ex.Message) Exit Sub End Try
lblListName.Text = "Listing of : " + zFile.Name.ToString lvZipContents.BeginUpdate() lvZipContents.Items.Clear()
For Each objEntry In zFile objItem = New ListViewItem(Path.GetFileName(objEntry.Name)) dtStamp = objEntry.DateTime objItem.SubItems.Add(objEntry.Size.ToString) objItem.SubItems.Add(objEntry.CompressedSize.ToString) objItem.SubItems.Add(dtStamp.ToString("yy-MM-dd")) objItem.SubItems.Add(dtStamp.ToString("t")) objItem.SubItems.Add(objEntry.Name.ToString) lvZipContents.Items.Add(objItem) Next
lvZipContents.EndUpdate() End Sub |
清单3:“释出”菜单项点击事件
Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles MenuItem1.Click Dim SelectedIndex As ListView.SelectedIndexCollection = lvZipContents.SelectedIndices Dim index As Integer
For Each index In SelectedIndex Dim s As ZipInputStream = New ZipInputStream(File.OpenRead(txtFileName.Text)) Dim directoryName As String = "/Program Files/createzipfile/"
Dim theEntry As ZipEntry theEntry = s.GetNextEntry() While (theEntry IsNot Nothing) Dim fileName As String = Path.GetFileName(theEntry.Name) If fileName.Equals(Path.GetFileName(lvZipContents.Items.Item(index).Text)) Then '生成解压目录 Directory.CreateDirectory(directoryName) '解压文件到指定的目录 Dim streamWriter As FileStream = File.Create(theEntry.Name) Dim size As Integer = 2048 Dim data(size) As Byte While (True) size = s.Read(data, 0, data.Length - 1) If (size > 0) Then streamWriter.Write(data, 0, size) Else Exit While End If End While streamWriter.Close() End If theEntry = s.GetNextEntry() End While s.Close() Next End Sub |