麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 編程 > .NET > 正文

用.NET 2.0壓縮/解壓功能處理大型數(shù)據(jù)

2020-01-18 01:54:06
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

摘要 如果你的應(yīng)用程序從未使用過(guò)壓縮,那么你很幸運(yùn)。而對(duì)于另一部分使用壓縮的開發(fā)人員來(lái)說(shuō),好消息是,.NET 2.0如今提供了兩個(gè)類來(lái)處理壓縮和解壓?jiǎn)栴}。本文正是想討論何時(shí)以及如何使用這些有用的工具。

引言

.NET框架2.0中的一個(gè)新名稱空間是System.IO.Compression。這個(gè)新名稱空間提供了兩個(gè)數(shù)據(jù)壓縮類:DeflateStream和GZipStream。這兩個(gè)壓縮類都支持無(wú)損壓縮和解壓,其設(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)用程序來(lái)展示壓縮的使用。該應(yīng)用程序允許你壓縮文件,包括普通文本文件。然后,你能夠把該示例中的代碼重用于你自己的應(yīng)用程序中。

首先,使用Visual Studio 2005創(chuàng)建一個(gè)新的Windows應(yīng)用程序并且使用下列控件來(lái)填充默認(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ì)于解壓來(lái)說(shuō),解壓存儲(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ì)象將被用來(lái)存儲(chǔ)壓縮數(shù)據(jù)。一旦壓縮完成,你需要計(jì)算壓縮比,這是用壓縮的數(shù)據(jù)的大小除以解壓數(shù)據(jù)的大小計(jì)算的。

然后,存儲(chǔ)在內(nèi)存流中的壓縮的數(shù)據(jù)被復(fù)制到另一個(gè)字節(jié)數(shù)組中并且被返回到調(diào)用函數(shù)。另外,你還要使用一個(gè)StopWatch對(duì)象來(lái)跟蹤該壓縮算法使用了多少時(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

'---用來(lái)存儲(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ù),你需要讀取來(lái)自流對(duì)象的數(shù)據(jù)。這是通過(guò)使用RetrieveBytesFromStream()函數(shù)來(lái)實(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

'---用來(lái)存儲(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)用例程來(lái)決定要讀取的最佳塊大小。

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ù)的大小作為塊大小確是一種好的辦法。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 亚洲射情 | 黄色网址在线免费 | 国产69精品久久久久9999不卡免费 | 黄色高清免费 | av性色全交蜜桃成熟时 | 九九久久视频 | 美国人成人在线视频 | 国产精品国产三级国产在线观看 | 亚洲一区二区成人 | 国产精品视频专区 | 狠狠色成色综合网 | 国产成人强伦免费视频网站 | 国产亚洲精品久久久久5区 日韩一级片一区二区三区 国产精品久久久久av | 91香草视频 | 亚洲午夜免费 | 看免费的毛片 | 日本在线播放一区二区三区 | 91久久国产综合久久91精品网站 | 精品一区二区三区中文字幕 | 成人免费久久网 | 欧美一区二区三区中文字幕 | 午夜久久电影 | 国产一国产一级毛片视频 | 嗯~啊~用力~高h | 斗破苍穹在线观看免费完整观看 | 国产一级中文字幕 | 91精品国产99久久久久久红楼 | 欧美精品一级 | 久久久久久久国产视频 | 欧美日韩电影在线 | 国产乱淫av | 成人性视频欧美一区二区三区 | 成人免费在线网 | 欧美日韩在线播放 | 免费一及片 | 国产精品免费一区二区 | 精品久久一区二区 | 成人在线网站 | 一级做受大片免费视频 | 久久91久久久久麻豆精品 | 久久久资源网 |