日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

用.NET 2.0压缩解压功能处理大型数据

發(fā)布時間:2025/3/19 asp.net 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用.NET 2.0压缩解压功能处理大型数据 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
摘要 如果你的應(yīng)用程序從未使用過壓縮,那么你很幸運。而對于另一部分使用壓縮的開發(fā)人員來說,好消息是,.NET 2.0如今提供了兩個類來處理壓縮和解壓問題。本文正是想討論何時以及如何使用這些有用的工具。

  引言

  .NET框架2.0中的一個新名稱空間是System.IO.Compression。這個新名稱空間提供了兩個數(shù)據(jù)壓縮類:DeflateStream和GZipStream。這兩個壓縮類都支持無損壓縮和解壓,其設(shè)計目的是為了處理流式數(shù)據(jù)的壓縮和解壓問題。

  壓縮是減少數(shù)據(jù)大小的有效辦法。例如,如果你有巨大量的數(shù)據(jù)存儲在你的SQL數(shù)據(jù)庫中,那么如果你在把這些數(shù)據(jù)保存到一個表之前壓縮一下,你就可以節(jié)省大量的磁盤空間。而且,既然現(xiàn)在你把更小塊的數(shù)據(jù)保存到你的數(shù)據(jù)庫中,花費在磁盤I/O方面的操作將會大大減少。壓縮的缺點是,它要求你的機(jī)器進(jìn)行另外的處理(因此需要另外的處理時間),并且,在你決定把壓縮應(yīng)用于你的程序之前,你需要計算這一部分時間。

  壓縮在你需要在網(wǎng)上傳送數(shù)據(jù)的情況中是極其有用的,特別是對于非常慢且代價昂貴的網(wǎng)絡(luò),例如GPRS連接。在這種情況中,使用壓縮能夠極大地縮小數(shù)據(jù)尺寸并且減少整個通訊耗費。Web服務(wù)是另一個領(lǐng)域-此時,使用壓縮能提供巨大的優(yōu)點,因為XML數(shù)據(jù)能被高度壓縮。

  但是一旦你認(rèn)為程序的性能代價值得使用壓縮,那么你將需要深入地理解.NET 2.0的兩個新的壓縮類,而這正是我想在本文中所闡述的。

  創(chuàng)建示例應(yīng)用程序

  在本文中,我將構(gòu)建一個示例應(yīng)用程序來展示壓縮的使用。該應(yīng)用程序允許你壓縮文件,包括普通文本文件。然后,你能夠把該示例中的代碼重用于你自己的應(yīng)用程序中。

  首先,使用Visual Studio 2005創(chuàng)建一個新的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

  在你開始使用壓縮類前,理解其工作原理是非常重要的。這些壓縮類從一個字節(jié)數(shù)組中讀取數(shù)據(jù),壓縮它并且把結(jié)果存儲到一個流對象中。對于解壓來說,解壓存儲到一個流對象中的數(shù)據(jù),然后把它存儲到另一個流對象中。

  首先,定義Compress()函數(shù),它有兩個參數(shù):algo和data。第一個參數(shù)指定使用哪種算法(GZip或Deflate);第二個參數(shù)是一個包含要壓縮的數(shù)據(jù)的字節(jié)數(shù)組。一個內(nèi)存流對象將被用來存儲壓縮數(shù)據(jù)。一旦壓縮完成,你需要計算壓縮比,這是用壓縮的數(shù)據(jù)的大小除以解壓數(shù)據(jù)的大小計算的。

  然后,存儲在內(nèi)存流中的壓縮的數(shù)據(jù)被復(fù)制到另一個字節(jié)數(shù)組中并且被返回到調(diào)用函數(shù)。另外,你還要使用一個StopWatch對象來跟蹤該壓縮算法使用了多少時間。Compress()函數(shù)定義如下:

Public Function Compress(ByVal algo As String, ByVal data() As Byte) As Byte()
Try
 Dim sw As New Stopwatch
 '---ms用于存儲壓縮的數(shù)據(jù)---
 Dim ms As New MemoryStream()
 Dim zipStream As Stream = Nothing
 '---開始秒表計時---
 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
 '---使用存儲在數(shù)據(jù)中的信息進(jìn)行壓縮---
 zipStream.Write(data, 0, data.Length)
 zipStream.Close()
 '---停止秒表---
 sw.Stop()
 '---計算壓縮比---
 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
 '---用來存儲壓縮了的數(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

  這個Decompress()函數(shù)將解壓由Compress()函數(shù)壓縮的數(shù)據(jù)。第一個參數(shù)指定要使用的算法。包含壓縮的數(shù)據(jù)的字節(jié)數(shù)組被作為第二個參數(shù)傳遞,然后它被復(fù)制到一個內(nèi)存流對象中。然后,這些壓縮類將解壓存儲在內(nèi)存流中的數(shù)據(jù),然后把解壓的數(shù)據(jù)存儲到另一個流對象中。為了獲得解壓的數(shù)據(jù),你需要讀取來自流對象的數(shù)據(jù)。這是通過使用RetrieveBytesFromStream()函數(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()
 '---使用存儲在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
 '---用來存儲解壓的數(shù)據(jù)---
 Dim dc_data() As Byte
 '---解壓的數(shù)據(jù)存儲于zipStream中;
 '把它們提取到一個字節(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

  這個RetrieveBytesFromStream()函數(shù)使用了兩個參數(shù):一個流對象,一個整數(shù),并返回一個包含解壓的數(shù)據(jù)的字節(jié)數(shù)組。這個整數(shù)參數(shù)用于決定每次把多少個字節(jié)從該流對象中讀取到字節(jié)數(shù)組中。這是必要的,因為當(dāng)數(shù)據(jù)被解壓時,你不知道存在于流對象中的解壓數(shù)據(jù)的大小。因此,有必要動態(tài)地把字節(jié)數(shù)組擴(kuò)展成塊以便存儲在運行時刻期間解壓縮的數(shù)據(jù)中。當(dāng)你不斷地擴(kuò)展字節(jié)數(shù)組時,塊太大會浪費內(nèi)存,而塊太小則會失去珍貴的時間。因此,可以由調(diào)用例程來決定要讀取的最佳塊大小。

  RetrieveBytesFromStream()函數(shù)的定義如下:

Public Function RetrieveBytesFromStream( _
ByVal stream As Stream, ByVal bytesblock As Integer) As Byte()
'---從一個流對象中檢索字節(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ù)大幾倍(由壓縮比所顯示),因此,在運行時刻期間你將至多動態(tài)地擴(kuò)展字節(jié)數(shù)組幾倍。作為一個例子,假定壓縮比是百分之20而壓縮的數(shù)據(jù)的大小為2MB,那么,在這種情況中,解壓的數(shù)據(jù)將是10MB。因此,該字節(jié)數(shù)組將被動態(tài)地擴(kuò)展5倍。理想情況下,在運行時刻期間該字節(jié)數(shù)組不應(yīng)該被擴(kuò)展太頻繁,因為這將會嚴(yán)重地減慢應(yīng)用程序運行速度。但是使用壓縮的數(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
'---用來存儲壓縮的數(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ù)制到一個字符串中---
 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ù)為一個字符串---
 txtAfter.Text = s.ToString
End Sub

  在txtBefore控件中的數(shù)據(jù)被轉(zhuǎn)換成一個字節(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
'---把壓縮的字符串格式化成一個字節(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)換成一個字節(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
'---讓用戶選擇一個要壓縮的文件--
 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)建一個包含壓縮的數(shù)據(jù)的新文件(具有一樣的文件名,但是加上了一個.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
 '---讓用戶選擇一個要解壓的文件---
 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)建一個包含解壓的數(shù)據(jù)的新文件(通過去掉它的.gzip擴(kuò)展名)。
測試應(yīng)用程序

  按F5測試應(yīng)用程序(見圖2)。


圖2.測試應(yīng)用程序:選擇使用的壓縮算法,然后你可以壓縮一個文本串或一個文件內(nèi)容。

  你應(yīng)該注意下列事實:

  · 壓縮小數(shù)量的文本實際上將會導(dǎo)致一種較大的壓縮文本。

  · 不同的文本將產(chǎn)生不同的壓縮比,盡管字符數(shù)是固定的。

  · 文本文件壓縮效果最好;它們能夠帶來最好的壓縮比。

  · 其它二進(jìn)制的文件,例如.exe,jpg,通常壓縮效果并不很好并且可能會導(dǎo)致大于百分比之100的壓縮比,這是沒有價值的。

  需要注意的是,.NET中的GZIP和Deflate算法的實現(xiàn)要比市場上的其它第三方GZIP工具具有較低的效率。盡管你能夠使用.NET類把10MB的數(shù)據(jù)壓縮到4MB,但是你發(fā)現(xiàn)使用一種第三方工具可能會達(dá)到一種更小的壓縮大小。另外,這個壓縮類無法操作大于4GB的數(shù)據(jù)。然而,在.NET中的實現(xiàn)將允許你解壓使用市場中的其它GZIP工具壓縮的所有的文件。

  小結(jié)

  在本文中,你已經(jīng)看到了如何在.NET 2.0中使用壓縮類。盡管這種實現(xiàn)還不如市場上的那些非MS方案有效,但是它的確為你提供了一種容易(免費)的方式來在你的.NET應(yīng)用程序中加入壓縮功能。

總結(jié)

以上是生活随笔為你收集整理的用.NET 2.0压缩解压功能处理大型数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 91岛国| 奴色虐av一区二区三区 | 男受被做哭激烈娇喘gv视频 | 国产高清自拍av | 狠狠人妻久久久久久综合蜜桃 | 岛国成人在线 | 国产女教师bbwbbwbbw | 亚洲AV无码精品色毛片浪潮 | 在线免费av网 | 男女h网站 | 日本裸体动漫 | 国产日韩一区二区三区在线观看 | 欧美性xxxxxxxxx| 久久成人福利视频 | 久久影院一区二区 | 亚洲视频a| 麻豆成人久久精品一区二区三区 | 国产一级片播放 | 国产亚洲av片在线观看18女人 | 亚洲欧洲在线视频 | 美女被男人插 | 美女福利视频网 | 裸体一区二区三区 | 久久视频中文字幕 | 国产精品xxx在线观看 | 在线观看日韩av | 91av亚洲| 男人天堂手机在线观看 | a在线观看免费 | 日韩精品中文字幕一区二区 | 久久久亚洲成人 | 日本一区免费 | www.99视频| 日韩激情国产 | 国产精品白嫩极品美女 | 免费毛片基地 | 亚洲精品一区二区三区中文字幕 | 国产麻豆一区 | 国产精品无码免费播放 | 末路1997全集免费观看完整版 | 香蕉视频国产 | 夜色在线影院 | 中文字幕自拍 | 中文字幕在线亚洲 | 亚洲激情电影在线 | 婷婷久久丁香 | 亚洲精品高潮 | 日本一区二区高清免费 | 国产精品入口日韩视频大尺度 | 欧美熟女一区二区 | freesexvideos第一次| 人人操日日干 | 日本成人毛片 | 日韩性色| 色版视频在线观看 | 久久av不卡 | 欧美国产专区 | 麻豆成人av | 国产三级自拍视频 | 人妻少妇被猛烈进入中文字幕 | 黄色免费小视频 | 久久人人人 | 日本久久爱 | 最好看的电影2019中文字幕 | 日本黄视频在线观看 | 亚洲第九十七页 | 美女隐私黄www网站动漫 | 伊人网五月天 | 欧美色v| 国产亚洲精品久久久久久无几年桃 | 日批视频在线播放 | 青青草97国产精品麻豆 | 国产一区二区在线视频观看 | 99re在线观看视频 | 亚洲欧美日韩图片 | 超碰超碰超碰超碰 | 免费在线一区二区三区 | 老司机深夜影院 | 亚洲视频在线观看一区 | 成人av激情 | 小sao货水好多真紧h无码视频 | 涩涩屋视频在线观看 | 亚洲综合日韩精品欧美综合区 | 国产一级二级毛片 | 亚洲一区二区三区四区在线播放 | 欧美日韩国产激情 | 欧美视频在线观看视频 | 魔性诱惑 | 亚洲国产精品999 | 色一情一交一乱一区二区三区 | 国产精品毛片一区二区 | 欧美性一区二区 | 乱老熟女一区二区三区 | 亚洲图片小说区 | 国产精品爱啪在线线免费观看 | 欧美丰满熟妇bbbbbb百度 | 中国少妇毛片 | 日本熟妇人妻中出 | 超碰v|