用.NET 2.0压缩解压功能处理大型数据
生活随笔
收集整理的這篇文章主要介紹了
用.NET 2.0压缩解压功能处理大型数据
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
摘要 如果你的應(yīng)用程序從未使用過壓縮,那么你很幸運(yùn)。而對(duì)于另一部分使用壓縮的開發(fā)人員來說,好消息是,.NET 2.0如今提供了兩個(gè)類來處理壓縮和解壓?jiǎn)栴}。本文正是想討論何時(shí)以及如何使用這些有用的工具。
引言
.NET框架2.0中的一個(gè)新名稱空間是System.IO.Compression。這個(gè)新名稱空間提供了兩個(gè)數(shù)據(jù)壓縮類:DeflateStream和GZipStream。這兩個(gè)壓縮類都支持無損壓縮和解壓,其設(shè)計(jì)目的是為了處理流式數(shù)據(jù)的壓縮和解壓?jiǎn)栴}。
壓縮是減少數(shù)據(jù)大小的有效辦法。例如,如果你有巨大量的數(shù)據(jù)存儲(chǔ)在你的SQL數(shù)據(jù)庫(kù)中,那么如果你在把這些數(shù)據(jù)保存到一個(gè)表之前壓縮一下,你就可以節(jié)省大量的磁盤空間。而且,既然現(xiàn)在你把更小塊的數(shù)據(jù)保存到你的數(shù)據(jù)庫(kù)中,花費(fèi)在磁盤I/O方面的操作將會(huì)大大減少。壓縮的缺點(diǎn)是,它要求你的機(jī)器進(jìn)行另外的處理(因此需要另外的處理時(shí)間),并且,在你決定把壓縮應(yīng)用于你的程序之前,你需要計(jì)算這一部分時(shí)間。
壓縮在你需要在網(wǎng)上傳送數(shù)據(jù)的情況中是極其有用的,特別是對(duì)于非常慢且代價(jià)昂貴的網(wǎng)絡(luò),例如GPRS連接。在這種情況中,使用壓縮能夠極大地縮小數(shù)據(jù)尺寸并且減少整個(gè)通訊耗費(fèi)。Web服務(wù)是另一個(gè)領(lǐng)域-此時(shí),使用壓縮能提供巨大的優(yōu)點(diǎn),因?yàn)閄ML數(shù)據(jù)能被高度壓縮。
但是一旦你認(rèn)為程序的性能代價(jià)值得使用壓縮,那么你將需要深入地理解.NET 2.0的兩個(gè)新的壓縮類,而這正是我想在本文中所闡述的。
創(chuàng)建示例應(yīng)用程序
在本文中,我將構(gòu)建一個(gè)示例應(yīng)用程序來展示壓縮的使用。該應(yīng)用程序允許你壓縮文件,包括普通文本文件。然后,你能夠把該示例中的代碼重用于你自己的應(yīng)用程序中。
首先,使用Visual Studio 2005創(chuàng)建一個(gè)新的Windows應(yīng)用程序并且使用下列控件來填充默認(rèn)的表單(見圖1):
· GroupBox控件
· RadioButton控件
· TextBox控件
· Button控件
· Label控件
切換到Form1的code-behind并且導(dǎo)入下列名稱空間:
在你開始使用壓縮類前,理解其工作原理是非常重要的。這些壓縮類從一個(gè)字節(jié)數(shù)組中讀取數(shù)據(jù),壓縮它并且把結(jié)果存儲(chǔ)到一個(gè)流對(duì)象中。對(duì)于解壓來說,解壓存儲(chǔ)到一個(gè)流對(duì)象中的數(shù)據(jù),然后把它存儲(chǔ)到另一個(gè)流對(duì)象中。
首先,定義Compress()函數(shù),它有兩個(gè)參數(shù):algo和data。第一個(gè)參數(shù)指定使用哪種算法(GZip或Deflate);第二個(gè)參數(shù)是一個(gè)包含要壓縮的數(shù)據(jù)的字節(jié)數(shù)組。一個(gè)內(nèi)存流對(duì)象將被用來存儲(chǔ)壓縮數(shù)據(jù)。一旦壓縮完成,你需要計(jì)算壓縮比,這是用壓縮的數(shù)據(jù)的大小除以解壓數(shù)據(jù)的大小計(jì)算的。
然后,存儲(chǔ)在內(nèi)存流中的壓縮的數(shù)據(jù)被復(fù)制到另一個(gè)字節(jié)數(shù)組中并且被返回到調(diào)用函數(shù)。另外,你還要使用一個(gè)StopWatch對(duì)象來跟蹤該壓縮算法使用了多少時(shí)間。Compress()函數(shù)定義如下:
這個(gè)Decompress()函數(shù)將解壓由Compress()函數(shù)壓縮的數(shù)據(jù)。第一個(gè)參數(shù)指定要使用的算法。包含壓縮的數(shù)據(jù)的字節(jié)數(shù)組被作為第二個(gè)參數(shù)傳遞,然后它被復(fù)制到一個(gè)內(nèi)存流對(duì)象中。然后,這些壓縮類將解壓存儲(chǔ)在內(nèi)存流中的數(shù)據(jù),然后把解壓的數(shù)據(jù)存儲(chǔ)到另一個(gè)流對(duì)象中。為了獲得解壓的數(shù)據(jù),你需要讀取來自流對(duì)象的數(shù)據(jù)。這是通過使用RetrieveBytesFromStream()函數(shù)來實(shí)現(xiàn)的(將在后面解釋)。
Decompress()函數(shù)的定義如下所示:
這個(gè)RetrieveBytesFromStream()函數(shù)使用了兩個(gè)參數(shù):一個(gè)流對(duì)象,一個(gè)整數(shù),并返回一個(gè)包含解壓的數(shù)據(jù)的字節(jié)數(shù)組。這個(gè)整數(shù)參數(shù)用于決定每次把多少個(gè)字節(jié)從該流對(duì)象中讀取到字節(jié)數(shù)組中。這是必要的,因?yàn)楫?dāng)數(shù)據(jù)被解壓時(shí),你不知道存在于流對(duì)象中的解壓數(shù)據(jù)的大小。因此,有必要?jiǎng)討B(tài)地把字節(jié)數(shù)組擴(kuò)展成塊以便存儲(chǔ)在運(yùn)行時(shí)刻期間解壓縮的數(shù)據(jù)中。當(dāng)你不斷地?cái)U(kuò)展字節(jié)數(shù)組時(shí),塊太大會(huì)浪費(fèi)內(nèi)存,而塊太小則會(huì)失去珍貴的時(shí)間。因此,可以由調(diào)用例程來決定要讀取的最佳塊大小。
RetrieveBytesFromStream()函數(shù)的定義如下:
注意,在Decompress()函數(shù)中,你調(diào)用了RetrieveBytesFromStream()函數(shù),如下所示:
塊大小是指壓縮的數(shù)據(jù)的大小(data.length)。在大多數(shù)情況中,解壓縮的數(shù)據(jù)要比壓縮的數(shù)據(jù)大幾倍(由壓縮比所顯示),因此,在運(yùn)行時(shí)刻期間你將至多動(dòng)態(tài)地?cái)U(kuò)展字節(jié)數(shù)組幾倍。作為一個(gè)例子,假定壓縮比是百分之20而壓縮的數(shù)據(jù)的大小為2MB,那么,在這種情況中,解壓的數(shù)據(jù)將是10MB。因此,該字節(jié)數(shù)組將被動(dòng)態(tài)地?cái)U(kuò)展5倍。理想情況下,在運(yùn)行時(shí)刻期間該字節(jié)數(shù)組不應(yīng)該被擴(kuò)展太頻繁,因?yàn)檫@將會(huì)嚴(yán)重地減慢應(yīng)用程序運(yùn)行速度。但是使用壓縮的數(shù)據(jù)的大小作為塊大小確是一種好的辦法。
處理壓縮事件
現(xiàn)在,既然定義好了主要的壓縮和解壓例程,那么接下來你就可以為各種按鈕進(jìn)行編碼了。相應(yīng)于Compress按鈕的事件處理器如下:
在txtBefore控件中的數(shù)據(jù)被轉(zhuǎn)換成一個(gè)字節(jié)數(shù)組,然后被壓縮。然后,該壓縮的數(shù)據(jù)被轉(zhuǎn)換成字符串以便于在txtAfter中顯示。
相應(yīng)于Decompress按鈕的事件處理器如下:
它把顯示在控件txtAfter中的數(shù)據(jù)轉(zhuǎn)換成一個(gè)字節(jié)數(shù)組,然后發(fā)送它以便進(jìn)行解壓。解壓縮的數(shù)據(jù)被顯示回txtBefore控件中。
相應(yīng)于"Select file to compress"按鈕的事件處理器代碼如下:
它讀取由用戶選擇的文件的內(nèi)容,壓縮它,并且創(chuàng)建一個(gè)包含壓縮的數(shù)據(jù)的新文件(具有一樣的文件名,但是加上了一個(gè).gzip擴(kuò)展名)。
相應(yīng)于"Select file to Decompress"按鈕的事件處理器代碼如下:
它讀取用戶選擇的文件的內(nèi)容,解壓之,并且創(chuàng)建一個(gè)包含解壓的數(shù)據(jù)的新文件(通過去掉它的.gzip擴(kuò)展名)。
測(cè)試應(yīng)用程序
按F5測(cè)試應(yīng)用程序(見圖2)。
你應(yīng)該注意下列事實(shí):
· 壓縮小數(shù)量的文本實(shí)際上將會(huì)導(dǎo)致一種較大的壓縮文本。
· 不同的文本將產(chǎn)生不同的壓縮比,盡管字符數(shù)是固定的。
· 文本文件壓縮效果最好;它們能夠帶來最好的壓縮比。
· 其它二進(jìn)制的文件,例如.exe,jpg,通常壓縮效果并不很好并且可能會(huì)導(dǎo)致大于百分比之100的壓縮比,這是沒有價(jià)值的。
需要注意的是,.NET中的GZIP和Deflate算法的實(shí)現(xiàn)要比市場(chǎng)上的其它第三方GZIP工具具有較低的效率。盡管你能夠使用.NET類把10MB的數(shù)據(jù)壓縮到4MB,但是你發(fā)現(xiàn)使用一種第三方工具可能會(huì)達(dá)到一種更小的壓縮大小。另外,這個(gè)壓縮類無法操作大于4GB的數(shù)據(jù)。然而,在.NET中的實(shí)現(xiàn)將允許你解壓使用市場(chǎng)中的其它GZIP工具壓縮的所有的文件。
小結(jié)
在本文中,你已經(jīng)看到了如何在.NET 2.0中使用壓縮類。盡管這種實(shí)現(xiàn)還不如市場(chǎng)上的那些非MS方案有效,但是它的確為你提供了一種容易(免費(fèi))的方式來在你的.NET應(yīng)用程序中加入壓縮功能。
引言
.NET框架2.0中的一個(gè)新名稱空間是System.IO.Compression。這個(gè)新名稱空間提供了兩個(gè)數(shù)據(jù)壓縮類:DeflateStream和GZipStream。這兩個(gè)壓縮類都支持無損壓縮和解壓,其設(shè)計(jì)目的是為了處理流式數(shù)據(jù)的壓縮和解壓?jiǎn)栴}。
壓縮是減少數(shù)據(jù)大小的有效辦法。例如,如果你有巨大量的數(shù)據(jù)存儲(chǔ)在你的SQL數(shù)據(jù)庫(kù)中,那么如果你在把這些數(shù)據(jù)保存到一個(gè)表之前壓縮一下,你就可以節(jié)省大量的磁盤空間。而且,既然現(xiàn)在你把更小塊的數(shù)據(jù)保存到你的數(shù)據(jù)庫(kù)中,花費(fèi)在磁盤I/O方面的操作將會(huì)大大減少。壓縮的缺點(diǎn)是,它要求你的機(jī)器進(jìn)行另外的處理(因此需要另外的處理時(shí)間),并且,在你決定把壓縮應(yīng)用于你的程序之前,你需要計(jì)算這一部分時(shí)間。
壓縮在你需要在網(wǎng)上傳送數(shù)據(jù)的情況中是極其有用的,特別是對(duì)于非常慢且代價(jià)昂貴的網(wǎng)絡(luò),例如GPRS連接。在這種情況中,使用壓縮能夠極大地縮小數(shù)據(jù)尺寸并且減少整個(gè)通訊耗費(fèi)。Web服務(wù)是另一個(gè)領(lǐng)域-此時(shí),使用壓縮能提供巨大的優(yōu)點(diǎn),因?yàn)閄ML數(shù)據(jù)能被高度壓縮。
但是一旦你認(rèn)為程序的性能代價(jià)值得使用壓縮,那么你將需要深入地理解.NET 2.0的兩個(gè)新的壓縮類,而這正是我想在本文中所闡述的。
創(chuàng)建示例應(yīng)用程序
在本文中,我將構(gòu)建一個(gè)示例應(yīng)用程序來展示壓縮的使用。該應(yīng)用程序允許你壓縮文件,包括普通文本文件。然后,你能夠把該示例中的代碼重用于你自己的應(yīng)用程序中。
首先,使用Visual Studio 2005創(chuàng)建一個(gè)新的Windows應(yīng)用程序并且使用下列控件來填充默認(rèn)的表單(見圖1):
| 圖1.填充表單:使用所有顯示的控件填充默認(rèn)的Form1。 |
· GroupBox控件
· RadioButton控件
· TextBox控件
· Button控件
· Label控件
切換到Form1的code-behind并且導(dǎo)入下列名稱空間:
| Imports System.IO Imports System.IO.Compression |
在你開始使用壓縮類前,理解其工作原理是非常重要的。這些壓縮類從一個(gè)字節(jié)數(shù)組中讀取數(shù)據(jù),壓縮它并且把結(jié)果存儲(chǔ)到一個(gè)流對(duì)象中。對(duì)于解壓來說,解壓存儲(chǔ)到一個(gè)流對(duì)象中的數(shù)據(jù),然后把它存儲(chǔ)到另一個(gè)流對(duì)象中。
首先,定義Compress()函數(shù),它有兩個(gè)參數(shù):algo和data。第一個(gè)參數(shù)指定使用哪種算法(GZip或Deflate);第二個(gè)參數(shù)是一個(gè)包含要壓縮的數(shù)據(jù)的字節(jié)數(shù)組。一個(gè)內(nèi)存流對(duì)象將被用來存儲(chǔ)壓縮數(shù)據(jù)。一旦壓縮完成,你需要計(jì)算壓縮比,這是用壓縮的數(shù)據(jù)的大小除以解壓數(shù)據(jù)的大小計(jì)算的。
然后,存儲(chǔ)在內(nèi)存流中的壓縮的數(shù)據(jù)被復(fù)制到另一個(gè)字節(jié)數(shù)組中并且被返回到調(diào)用函數(shù)。另外,你還要使用一個(gè)StopWatch對(duì)象來跟蹤該壓縮算法使用了多少時(shí)間。Compress()函數(shù)定義如下:
| Public Function Compress(ByVal algo As String, ByVal data() As Byte) As Byte() Try Dim sw As New Stopwatch '---ms用于存儲(chǔ)壓縮的數(shù)據(jù)--- Dim ms As New MemoryStream() Dim zipStream As Stream = Nothing '---開始秒表計(jì)時(shí)--- sw.Start() If algo = "Gzip" Then zipStream = New GZipStream(ms, CompressionMode.Compress, True) ElseIf algo = "Deflate" Then zipStream = New DeflateStream(ms, CompressionMode.Compress, True) End If '---使用存儲(chǔ)在數(shù)據(jù)中的信息進(jìn)行壓縮--- zipStream.Write(data, 0, data.Length) zipStream.Close() '---停止秒表--- sw.Stop() '---計(jì)算壓縮比--- Dim ratio As Single = Math.Round((ms.Length / data.Length) * 100, 2) Dim msg As String = "Original size: " & data.Length & _ ", Compressed size: " & ms.Length & _ ", 壓縮比: " & ratio & "%" & _ ", Time spent: " & sw.ElapsedMilliseconds & "ms" lblMessage.Text = msg ms.Position = 0 '---用來存儲(chǔ)壓縮了的數(shù)據(jù)(字節(jié)數(shù)組)--- Dim c_data(ms.Length - 1) As Byte '---把內(nèi)存流的內(nèi)容讀取到字節(jié)數(shù)組--- ms.Read(c_data, 0, ms.Length) Return c_data Catch ex As Exception MsgBox(ex.ToString) Return Nothing End Try End Function |
這個(gè)Decompress()函數(shù)將解壓由Compress()函數(shù)壓縮的數(shù)據(jù)。第一個(gè)參數(shù)指定要使用的算法。包含壓縮的數(shù)據(jù)的字節(jié)數(shù)組被作為第二個(gè)參數(shù)傳遞,然后它被復(fù)制到一個(gè)內(nèi)存流對(duì)象中。然后,這些壓縮類將解壓存儲(chǔ)在內(nèi)存流中的數(shù)據(jù),然后把解壓的數(shù)據(jù)存儲(chǔ)到另一個(gè)流對(duì)象中。為了獲得解壓的數(shù)據(jù),你需要讀取來自流對(duì)象的數(shù)據(jù)。這是通過使用RetrieveBytesFromStream()函數(shù)來實(shí)現(xiàn)的(將在后面解釋)。
Decompress()函數(shù)的定義如下所示:
| Public Function Decompress(ByVal algo As String, ByVal data() As Byte) As Byte() Try Dim sw As New Stopwatch '---復(fù)制數(shù)據(jù)(壓縮的)到ms--- Dim ms As New MemoryStream(data) Dim zipStream As Stream = Nothing '---開始秒表--- sw.Start() '---使用存儲(chǔ)在ms中的數(shù)據(jù)解壓--- If algo = "Gzip" Then zipStream = New GZipStream(ms, CompressionMode.Decompress) ElseIf algo = "Deflate" Then zipStream = New DeflateStream(ms, CompressionMode.Decompress, True) End If '---用來存儲(chǔ)解壓的數(shù)據(jù)--- Dim dc_data() As Byte '---解壓的數(shù)據(jù)存儲(chǔ)于zipStream中; '把它們提取到一個(gè)字節(jié)數(shù)組中--- dc_data = RetrieveBytesFromStream(zipStream, data.Length) '---停止秒表--- sw.Stop() lblMessage.Text = "Decompression completed. Time spent: " & _ sw.ElapsedMilliseconds & "ms" & _ ", Original size: " & dc_data.Length Return dc_data Catch ex As Exception MsgBox(ex.ToString) Return Nothing End Try End Function |
這個(gè)RetrieveBytesFromStream()函數(shù)使用了兩個(gè)參數(shù):一個(gè)流對(duì)象,一個(gè)整數(shù),并返回一個(gè)包含解壓的數(shù)據(jù)的字節(jié)數(shù)組。這個(gè)整數(shù)參數(shù)用于決定每次把多少個(gè)字節(jié)從該流對(duì)象中讀取到字節(jié)數(shù)組中。這是必要的,因?yàn)楫?dāng)數(shù)據(jù)被解壓時(shí),你不知道存在于流對(duì)象中的解壓數(shù)據(jù)的大小。因此,有必要?jiǎng)討B(tài)地把字節(jié)數(shù)組擴(kuò)展成塊以便存儲(chǔ)在運(yùn)行時(shí)刻期間解壓縮的數(shù)據(jù)中。當(dāng)你不斷地?cái)U(kuò)展字節(jié)數(shù)組時(shí),塊太大會(huì)浪費(fèi)內(nèi)存,而塊太小則會(huì)失去珍貴的時(shí)間。因此,可以由調(diào)用例程來決定要讀取的最佳塊大小。
RetrieveBytesFromStream()函數(shù)的定義如下:
| Public Function RetrieveBytesFromStream( _ ByVal stream As Stream, ByVal bytesblock As Integer) As Byte() '---從一個(gè)流對(duì)象中檢索字節(jié)--- Dim data() As Byte Dim totalCount As Integer = 0 Try While True '---逐漸地增加數(shù)據(jù)字節(jié)數(shù)組-的大小-- ReDim Preserve data(totalCount + bytesblock) Dim bytesRead As Integer = stream.Read(data, totalCount, bytesblock) If bytesRead = 0 Then Exit While End If totalCount += bytesRead End While '---確保字節(jié)數(shù)組正確包含提取的字節(jié)數(shù)--- ReDim Preserve data(totalCount - 1) Return data Catch ex As Exception MsgBox(ex.ToString) Return Nothing End Try End Function |
注意,在Decompress()函數(shù)中,你調(diào)用了RetrieveBytesFromStream()函數(shù),如下所示:
| dc_data = RetrieveBytesFromStream(zipStream, data.Length) |
塊大小是指壓縮的數(shù)據(jù)的大小(data.length)。在大多數(shù)情況中,解壓縮的數(shù)據(jù)要比壓縮的數(shù)據(jù)大幾倍(由壓縮比所顯示),因此,在運(yùn)行時(shí)刻期間你將至多動(dòng)態(tài)地?cái)U(kuò)展字節(jié)數(shù)組幾倍。作為一個(gè)例子,假定壓縮比是百分之20而壓縮的數(shù)據(jù)的大小為2MB,那么,在這種情況中,解壓的數(shù)據(jù)將是10MB。因此,該字節(jié)數(shù)組將被動(dòng)態(tài)地?cái)U(kuò)展5倍。理想情況下,在運(yùn)行時(shí)刻期間該字節(jié)數(shù)組不應(yīng)該被擴(kuò)展太頻繁,因?yàn)檫@將會(huì)嚴(yán)重地減慢應(yīng)用程序運(yùn)行速度。但是使用壓縮的數(shù)據(jù)的大小作為塊大小確是一種好的辦法。
處理壓縮事件
現(xiàn)在,既然定義好了主要的壓縮和解壓例程,那么接下來你就可以為各種按鈕進(jìn)行編碼了。相應(yīng)于Compress按鈕的事件處理器如下:
| Private Sub btnCompress_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnCompress.Click '---用來存儲(chǔ)壓縮的數(shù)據(jù)--- Dim compressedData() As Byte '---壓縮數(shù)據(jù)--- If rbGZipStream.Checked Then compressedData = Compress("Gzip",System.Text.Encoding.ASCII.GetBytes(txtBefore.Text)) Else compressedData = Compress("Deflate",System.Text.Encoding.ASCII.GetBytes(txtBefore.Text)) End If '---把壓縮的數(shù)據(jù)復(fù)制到一個(gè)字符串中--- Dim i As Integer Dim s As New System.Text.StringBuilder() For i = 0 To compressedData.Length - 1 If i <> compressedData.Length - 1 Then s.Append(compressedData(i) & " ") Else s.Append(compressedData(i)) End If Next '---顯示壓縮的數(shù)據(jù)為一個(gè)字符串--- txtAfter.Text = s.ToString End Sub |
在txtBefore控件中的數(shù)據(jù)被轉(zhuǎn)換成一個(gè)字節(jié)數(shù)組,然后被壓縮。然后,該壓縮的數(shù)據(jù)被轉(zhuǎn)換成字符串以便于在txtAfter中顯示。
相應(yīng)于Decompress按鈕的事件處理器如下:
| Private Sub btnDecompress_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnDecompress.Click '---把壓縮的字符串格式化成一個(gè)字節(jié)數(shù)組--- Dim eachbyte() As String = txtAfter.Text.Split(" ") Dim data(eachbyte.Length - 1) As Byte For i As Integer = 0 To eachbyte.Length - 1 data(i) = Convert.ToByte(eachbyte(i)) Next '---解壓數(shù)據(jù)并且顯示解壓的數(shù)據(jù)--- If rbGZipStream.Checked Then txtBefore.Text = System.Text.Encoding.ASCII.GetString(Decompress("Gzip", data)) Else txtBefore.Text = System.Text.Encoding.ASCII.GetString(Decompress("Deflate", data)) End If End Sub |
它把顯示在控件txtAfter中的數(shù)據(jù)轉(zhuǎn)換成一個(gè)字節(jié)數(shù)組,然后發(fā)送它以便進(jìn)行解壓。解壓縮的數(shù)據(jù)被顯示回txtBefore控件中。
相應(yīng)于"Select file to compress"按鈕的事件處理器代碼如下:
| Private Sub btnSelectFile_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnSelectFile.Click '---讓用戶選擇一個(gè)要壓縮的文件-- Dim openFileDialog1 As New OpenFileDialog() 'openFileDialog1.InitialDirectory = "c:" openFileDialog1.Filter = "All files (*.*)|*.*" openFileDialog1.RestoreDirectory = True If openFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then '---把文件的內(nèi)容讀入字節(jié)數(shù)組--- Dim fileContents As Byte() fileContents = My.Computer.FileSystem.ReadAllBytes(openFileDialog1.FileName) '---創(chuàng)建gzip文件--- Dim filename As String = openFileDialog1.FileName & ".gzip" If File.Exists(filename) Then File.Delete(filename) Dim fs As FileStream = New FileStream(filename, FileMode.CreateNew, FileAccess.Write) '---壓縮文件的內(nèi)容--- Dim compressed_Data As Byte() If rbGZipStream.Checked Then compressed_Data = Compress("Gzip", fileContents) Else compressed_Data = Compress("Deflate", fileContents) End If If compressed_Data IsNot Nothing Then '---把壓縮的內(nèi)容寫進(jìn)壓縮的文件中--- fs.Write(compressed_Data, 0, compressed_Data.Length) fs.Close() End If End If End Sub |
它讀取由用戶選擇的文件的內(nèi)容,壓縮它,并且創(chuàng)建一個(gè)包含壓縮的數(shù)據(jù)的新文件(具有一樣的文件名,但是加上了一個(gè).gzip擴(kuò)展名)。
相應(yīng)于"Select file to Decompress"按鈕的事件處理器代碼如下:
| Private Sub btnDecompressFile_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnDecompressFile.Click '---讓用戶選擇一個(gè)要解壓的文件--- Dim openFileDialog1 As New OpenFileDialog() ' openFileDialog1.InitialDirectory = "c:" openFileDialog1.Filter = "All GZIP files (*.gzip)|*.gzip" openFileDialog1.RestoreDirectory = True If openFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then '---把壓縮的文件的內(nèi)容讀入到字節(jié)數(shù)組--- Dim fileContents As Byte() fileContents = My.Computer.FileSystem.ReadAllBytes(openFileDialog1.FileName) '---解壓文件的內(nèi)容--- Dim uncompressed_Data As Byte() If rbGZipStream.Checked Then uncompressed_Data = Decompress("Gzip", fileContents) Else uncompressed_Data = Decompress("Deflat", fileContents) End If '---創(chuàng)建解壓的文件--- Dim filename As String = openFileDialog1.FileName.Substring(0, openFileDialog1.FileName.Length - 5) If File.Exists(filename) Then File.Delete(filename) Dim fs As FileStream = New FileStream(filename,FileMode.CreateNew, FileAccess.Write) If uncompressed_Data IsNot Nothing Then '---把解壓內(nèi)容寫入到文件中--- fs.Write(uncompressed_Data, 0, uncompressed_Data.Length) fs.Close() End If End If End Sub |
它讀取用戶選擇的文件的內(nèi)容,解壓之,并且創(chuàng)建一個(gè)包含解壓的數(shù)據(jù)的新文件(通過去掉它的.gzip擴(kuò)展名)。
測(cè)試應(yīng)用程序
按F5測(cè)試應(yīng)用程序(見圖2)。
| 圖2.測(cè)試應(yīng)用程序:選擇使用的壓縮算法,然后你可以壓縮一個(gè)文本串或一個(gè)文件內(nèi)容。 |
你應(yīng)該注意下列事實(shí):
· 壓縮小數(shù)量的文本實(shí)際上將會(huì)導(dǎo)致一種較大的壓縮文本。
· 不同的文本將產(chǎn)生不同的壓縮比,盡管字符數(shù)是固定的。
· 文本文件壓縮效果最好;它們能夠帶來最好的壓縮比。
· 其它二進(jìn)制的文件,例如.exe,jpg,通常壓縮效果并不很好并且可能會(huì)導(dǎo)致大于百分比之100的壓縮比,這是沒有價(jià)值的。
需要注意的是,.NET中的GZIP和Deflate算法的實(shí)現(xiàn)要比市場(chǎng)上的其它第三方GZIP工具具有較低的效率。盡管你能夠使用.NET類把10MB的數(shù)據(jù)壓縮到4MB,但是你發(fā)現(xiàn)使用一種第三方工具可能會(huì)達(dá)到一種更小的壓縮大小。另外,這個(gè)壓縮類無法操作大于4GB的數(shù)據(jù)。然而,在.NET中的實(shí)現(xiàn)將允許你解壓使用市場(chǎng)中的其它GZIP工具壓縮的所有的文件。
小結(jié)
在本文中,你已經(jīng)看到了如何在.NET 2.0中使用壓縮類。盡管這種實(shí)現(xiàn)還不如市場(chǎng)上的那些非MS方案有效,但是它的確為你提供了一種容易(免費(fèi))的方式來在你的.NET應(yīng)用程序中加入壓縮功能。
總結(jié)
以上是生活随笔為你收集整理的用.NET 2.0压缩解压功能处理大型数据的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Asp中一些FSO方面的函数
- 下一篇: 为你的电脑系统清除淤塞的垃圾!(不用任何