Imports System.Data Imports System.Data.SqlClient Imports System.Diagnostics Imports System.IO Imports System.IO.Compression Imports System.Text.Encoding다음으로 getRecords() 웹 메소드를 정의하여 그것이 Northwind 데이터베이스로부터 Employee 테이블을 데이터집합으로서(바이트 배열로 노출된다) 반환하도록 한다.
C:SQL Server 2000 Sample Databases>sqlcmd -S .SQLEXPRESS -i instpubs.sql C:SQL Server 2000 Sample Databases>sqlcmd -S .SQLEXPRESS -i instnwnd.sql필자가 데이터집합을 데이터집합 객체로 반환하는 대신 그것을 바이트 배열로 반환하도록 하였음에 주목하라. 이것은 나중에 압축을 용이하게 해준다._ Public Function getRecords() As Byte() Dim connStr As String = _ "Data Source=.SQLEXPRESS;Initial Catalog=Northwind;" & _ "Integrated Security=True" Dim sql As String = "SELECT * FROM Employees" Dim conn As SqlConnection = New SqlConnection(connStr) Dim comm As SqlCommand = New SqlCommand(sql, conn) Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm) Dim ds As DataSet = New DataSet() "---연결을 열고 데이터 집합을 채운다 --- conn.Open() dataadapter.Fill(ds, "Employees_table") conn.Close() "---데이터 집합을 XML로 변환한다 --- Dim datadoc As System.Xml.XmlDataDocument = _ New System.Xml.XmlDataDocument(ds) Dim dsXML As String = datadoc.InnerXml Return ASCII.GetBytes(dsXML) End Function
http://localhost:11496/DatasetWS/Service.asmx11496은 비주얼 스튜디오 2005가 내 웹 서비스를 실행하는데 사용한 임의의 포트번호이다. 여러분의 컴퓨터에서는 다른 숫자를 가질 것이다.
Imports System.IO Imports System.IO.Compression Imports System.Text.Encoding Double-click on the Load button to switch to its event handler. Code the following: Private Sub btnLoad_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnLoad.Click "---웹 서비스에 프록시 객체를 생성한다--- Dim ws As New dataWS.Service "---데이터 집합 객체를 생성한다 --- Dim ds As New DataSet "---스톱워치 객체를 생성한다 --- Dim sw1, sw2 As New Stopwatch "---다운로드에 소요된 시간을 잰다 --- sw1.Start() "---웹 서비스에 접속한다--- Dim dsBytes As Byte() = ws.getRecords Label1.Text = "Size of download: " & dsBytes.Length "---바이트 배열을 문자열로 변환한 다음 " 데이터 집합 객체로 읽어들인다 --- ds.ReadXml(New IO.StringReader(ASCII.GetString(dsBytes))) sw1.Stop() Label2.Text = "Time spent: " & sw1.ElapsedMilliseconds & "ms" "---DataGridView 컨트롤에 바인딩시킨다 --- DataGridView1.DataSource = ds DataGridView1.DataMember = "Employees_table" End Sub본질적으로 이것은 데이터 집합을 읽어오기 위해 웹 서비스에 접속한 다음 읽어온 데이터 집합을DataGridView 컨트롤에 바인딩 시킨다. 애플리케이션을 테스트하기 위해 F5를 누른다. Load 버튼을 클릭하고 나면 DataGridView 컨트롤이 나타날 것이다. 그림 3은 그 결과를 보여준다.
Public Function Compress(ByVal data() As Byte) As Byte() Try "---ms는 압축된 데이터를 저장하는데 사용된다 --- Dim ms As New MemoryStream() Dim zipStream As Stream = Nothing zipStream = New GZipStream(ms, _ CompressionMode.Compress, True) "---혹은--- "zipStream = New DeflateStream(ms, _ " CompressionMode.Compress, True) "---데이터에 저장되어 있는 정보를 이용하여 압축함 --- zipStream.Write(data, 0, data.Length) zipStream.Close() ms.Position = 0 "---압축된 데이터(바이트 배열)를 저장하는데 사용한다--- Dim compressed_data(ms.Length - 1) As Byte "---메모리 스트림의 내용을 바이트 배열로 읽어들인다--- ms.Read(compressed_data, 0, ms.Length) Return compressed_data Catch ex As Exception Return Nothing End Try End Function기본적으로 이 함수는 GZipStream 클래스를 이용하여 바이트 배열에 저장되어 있는 데이터를 압축한 다음 압축된 데이터를 스트림 객체에 저장한다. 그런 다음 압축된 데이터는 바이트 배열로 반환된다.
압축해제 하기_ Public Function getRecords() As Byte() Dim connStr As String = _ "Data Source=.SQLEXPRESS;Initial Catalog=Northwind;" & _ "Integrated Security=True" Dim sql As String = "SELECT * FROM Employees" Dim conn As SqlConnection = New SqlConnection(connStr) Dim comm As SqlCommand = New SqlCommand(sql, conn) Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm) Dim ds As DataSet = New DataSet() "---연결을 열고 데이터 집합을 채운다 --- conn.Open() dataadapter.Fill(ds, "Employees_table") conn.Close() "---데이터 집합을 XML로 변환한다 --- Dim datadoc As System.Xml.XmlDataDocument = _ New System.Xml.XmlDataDocument(ds) Dim dsXML As String = datadoc.InnerXml "---압축을 수행한다 --- Dim compressedDS() As Byte compressedDS = Compress(UTF8.GetBytes(dsXML)) Return compressedDS "------------------------- End Function
Public Function Decompress(ByVal data() As Byte) As Byte() Try "---압축된 데이터를 ms로 복사한다 --- Dim ms As New MemoryStream(data) Dim zipStream As Stream = Nothing "---ms에 저장되어 있는 데이터를 이용하여 압축해제한다 --- zipStream = New GZipStream(ms, CompressionMode.Decompress) "---혹은--- "zipStream = New DeflateStream(ms, _ " CompressionMode.Decompress, True) "---압축해제된 데이터를 저장하는 데 사용한다 --- Dim dc_data() As Byte "---압축해제된 데이터는 zipStream에 저장되며; " 그것들을 바이트 배열로 추출한다 --- dc_data = ExtractBytesFromStream(zipStream, data.Length) Return dc_data Catch ex As Exception Return Nothing End Try End Function압축된 데이터는 메모리 스트림 객체로 복사된 다음 GZipStream 클래스를 이용하여 압축해제 된다. 압축 해제된 데이터는 ExtractFromStream() 메소드를 이용하여 바이트 배열로 추출되는데 이것은 아래에 정의되어 있다:
Public Function ExtractBytesFromStream( _ ByVal stream As Stream, _ ByVal dataBlock As Integer) _ As Byte() "---스트림 객체로부터 바이트를 추출한다 --- Dim data() As Byte Dim totalBytesRead As Integer = 0 Try While True "---점진적으로 데이터 바이트 배열의 크기를 증가시킨다 --- ReDim Preserve data(totalBytesRead + dataBlock) Dim bytesRead As Integer = _ stream.Read(data, totalBytesRead, dataBlock) If bytesRead = 0 Then Exit While End If totalBytesRead += bytesRead End While "---바이트 배열이 추출된 바이트의 수를 정확하게 포함하고 있는지 확인하라--- ReDim Preserve data(totalBytesRead - 1) Return data Catch ex As Exception Return Nothing End Try End Function여러분이 압축해제된 데이터의 실제 크기를 알 수 없기 때문에 압축해제된 데이터를 저장하는데 사용되는 데이터 배열의 크기를 점진적으로 증가시켜야만 한다. dataBlock 파라미터는 한번에 복사된 데이터의 수를 알려준다. 쓸만한 어림잡이 계산은 다음과 같이 압축된 데이터의 크기를 블록 사이즈로 이용하는 것이다.
"---데이터는 압축된 데이터를 포함하는 배열이다 dc_data = ExtractBytesFromStream(zipStream, data.Length)getRecords() 웹 메소드에 의해 반환되는 데이터가 지금은 압축되어 있기 때문에 그것을 데이터 집합 객체로 불려질 수 있기 이전에 압축해야 할 필요가 있다. Load 버튼 이벤트 핸들러를 다음과 같이 수정한다:
Private Sub btnLoad_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnLoad.Click "---웹 서비스에서 프록시 객체를 생성한다 --- Dim ws As New dataWS.Service "---데이터 집합 객체를 생성한다 --- Dim ds As New DataSet "---스톱워치 객체를 생성한다 --- Dim sw1, sw2 As New Stopwatch sw1.Start() Dim dsBytes As Byte() = ws.getRecords Label1.Text = "Size of download: " & dsBytes.Length "---압축해제를 수행한다 --- Dim decompressed_dsBytes() As Byte sw2.Start() decompressed_dsBytes = Decompress(dsBytes) sw2.Stop() Label3.Text = "Decompression took: " & _ sw2.ElapsedMilliseconds & "ms" ds.ReadXml(New _ IO.StringReader(ASCII.GetString(decompressed_dsBytes))) "--------------------------- sw1.Stop() Label2.Text = "Time spent: " & sw1.ElapsedMilliseconds & "ms" DataGridView1.DataSource = ds DataGridView1.DataMember = "Employees_table" End Sub필자는 또한 압축 해제를 수행하는데 시간이 얼마나 걸리는 지도 재어 보았는데 여러분이 직접 압축 해제를 수행하는데 실질적으로 걸리는 시간이 얼마인지를 확인해 보는 것도 괜찮은 생각이다.
태스크 | 다운로드 크기(바이트) | 소요시간(ms) | 압축해제 시간(ms) |
압축기능 사용하지 않음 | 266330 | 65 | - |
압축기능 사용 | 124148 | 83 | 13 |
최신 콘텐츠