search
Twitter Rss Feeds
MicrosoftArticlesForumsGroups
C# .NET
VB.NET
Visual Studio .NET
ADO.NET
Xml/Xslt
VB 6.0
.NET CF
GDI+
LINQ
Deployment
Security
FoxPro
Silverlight / WPF
Entity Framework
RIA Services

Web ProgrammingArticlesForumsGroups
JavaScript
ASP
ASP.NET
Web Services

Non-MicrosoftArticlesForumsGroups
NHibernate
Perl
PHP
Ruby
Java
Linux / Unix
Apple
Open Source

DatabasesArticlesForumsGroups
SQL Server
Access
Oracle
MySQL
Other Databases

OfficeArticlesForumsGroups
Microsoft Excel
Microsoft Word
Microsoft Powerpoint
Publisher
Money

Operating SystemsArticlesForumsGroups
Windows 7
Windows Server
Windows Vista
Windows XP
Windows Update
MAC
Linux / UNIX

Server PlatformsArticlesForumsGroups
Share Point
BizTalk
Site Server
Exhange Server
IIS
Transaction Server

Graphic DesignArticlesForumsGroups
Macromedia Flash
Adobe PhotoShop
Microsoft Expression

OtherArticlesForumsGroups
Subversion / CVS
Ask Dr. Dotnetsky
Active Directory
Networking
Uninstall Virus
Job Openings
Reviews
Search Engines
Resumes

 
In-Memory Data Compression in .NET, PART III

By Peter A. Bromberg, Ph.D.

Peter Bromberg  

In my first article of this series, "In-Memory Data Compression in .NET", I illustrated the use of Mike Krüger of icSharpcode.net 's NZipLib 100% C# ZLib port to compress and decompress strings in memory. The next logical step, is "How do I send the stuff over the wire compressed, decompress it , do some work and then recompress it and send back the response?" If you are not familiar with ZLib or data compression, I suggest you review the first article before reading this one.

In the second article, In-Memory Data Compression in .NET, PART II I followed up with ASP.NET code showing how to dynamically compress and send any textual data to a "receiver.aspx" page, decompress on the server, do some work, then recompress and return the response, where the client page automatically decompresses it.

There is another important facet to in-memory data compression and web servers - namely, HTTP compression. By default, Internet Information Services (IIS) 5.0 uses the GZip and Deflate HTTP compression methods. Both compression methods are implemented through an ISAPI filter. HTTP compression is a subservice of IIS, which is handled through an ISAPI filter. Because this filter is installed at the WWW Service level, compression must be configured for the entire Web server. It cannot be configured for a specific Web site. The following two files handle this compression (located in the %WinDir%\System32\INETSERV folder):
CompFilt.dll
GZIP.dll
Compression Methods
GZIP file format specification - RFC 1952
DEFLATE Compressed Data Format Specification - RFC 1951

To tell the browser that the server is sending compressed content, we only need to set the "Content-Encoding" Response Header to "gzip". Unfortunately, all web servers that I know of are unable to generate dynamically compressed data - the files need to actually be set up as compressed in advance. Fortunately, with a compression library, we now have an easy way to take ANY textual content - XML, HTML etc. regardless of whether it is generated from an uncompressed file or generated in memory say, from the results of a database query, GZip it, set the header, and send it on it's merry way to the browser, nicely compressed! The code that follows is a simplified but complete example of how we would read a specified file from the filesystem, compress it, and send it on to the browser which should be able to handle the decompression by itself:

 
<% @ Page Language="C#" %>
<% @Import Namespace="System" %>
<% @Import Namespace="System.Text" %>
<% @Import Namespace="System.IO" %>
<% @Import Namespace="System.Net" %>
<% @Import Namespace="System.Text" %>
<% @Import Namespace="NZlib.GZip" %>
<% @Import Namespace="System.Xml" %>
<script language="C#" runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
Response.AppendHeader("Content-Encoding", "gzip");
Response.BinaryWrite(GzipCompress(@"C:\Inetpub\wwwroot\stuff\Mybigdocument.htm"));
}
private byte[] GzipCompress(string strFilePathName)
{
try
{

FileStream fs = File.OpenRead(strFilePathName);
byte[] writeData = new byte[fs.Length];
fs.Read(writeData, 0, (int)fs.Length);
MemoryStream ms = new MemoryStream();
NZlib.GZip.GZipOutputStream s = new NZlib.GZip.GZipOutputStream(ms);
s.Write(writeData, 0, writeData.Length);
s.Flush();
s.Close();
byte[] compressedData = (byte[])ms.ToArray();
return compressedData;
}
catch(Exception e)
{
Response.Write(e.Message);
return null;
}
}
</script>

Of course, we don't have to read the file from the file system, it could just as easily be in a string variable that we have just finished concatenating based on some specific processing code rules. Here is another example that takes string input and uses GZip compression to write it out to the browser:

<% @ Page Language="C#" %>
<% @Import Namespace="System.IO" %>
<% @Import Namespace="NZlib.GZip" %>

<script language="C#" runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
Response.AppendHeader("Content-Encoding", "gzip");
string strInput ="<HTML><HEAD></HEAD><BODY><Table border=1 bordercolor=red cellspacing=2 cellpadding=2><TR BGCOLOR=lightgrey><TD>this is some data</TD></TR></TABLE></BODY></HTML>";
Response.BinaryWrite(GzipCompressString(strInput));
}

private byte[] GzipCompressString(string strInput)
{
try
{
byte[] writeData = System.Text.Encoding.ASCII.GetBytes(strInput);
MemoryStream ms = new MemoryStream();
NZlib.GZip.GZipOutputStream s = new NZlib.GZip.GZipOutputStream(ms);
s.Write(writeData, 0, writeData.Length);
s.Flush();
s.Close();
byte[] compressedData = (byte[])ms.ToArray();
return compressedData;
}
catch(Exception e)
{
Response.Write(e.Message);
return null;
}
}
</script>

 

 

HTTP compression reduces server load and bandwidth needs, and most modern browsers can decompress GZip or deflated compressed data. By using Dynamic GZip or Deflate compression to compress our dynamically generated content in ASP.NET, we can take advantage of the native HTTP decompression built into modern browsers and obtain valuable time and bandwidth savings, while reducing server load and increasing the scalability of our webserver(s).

This concludes my series on In - Memory Data Compression in .NET. I hope you found it useful!

Peter Bromberg is an independent consultant specializing in distributed .NET solutions in Orlando and a co-developer of the EggheadCafe.com developer website. He can be reached at pbromberg@yahoo.com

 
Do you have a question or comment about this article? Have a programming problem you need to solve? Post it at eggheadcafe.com forums and receive immediate email notification of responses.


Pete's Blog   |    Pete's Resume   |    Robbe's Blog   |    Robbe's Resume   |    Archive #2   |    Archive #3   |    Dotnetslackers   |    XmlPitStop   |    Advertise   |   Contact Us   |   Privacy   |   Copyright (c) 2000 - 2009 eggheadcafe.com  All rights reserved.