Posts RSS Comments RSS 137 Posts and 271 Comments till now

Archive for the 'Programming' Category

Using Serialization To Measure .NET DataSet Size

In my previous post, I did commented that serialization could do the trick to measure the size of a DataSet object.

 

I am using both BinaryFormatter and SoapFormatter this time, the code is as follows:

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;
using System.Runtime.Serialization.Formatters.Binary;

namespace ConsoleApplication1
{
    class Program
    {
        public static int MeasureDataSetByXML(DataSet ds)
        {
            String firstXML = ds.GetXml();
            UnicodeEncoding uniEnc = new UnicodeEncoding();
            return uniEnc.GetByteCount(firstXML);
        }

        public static long MeasureDataSetByBinaryFormatter(DataSet ds)
        {
            return MeasureDataSetSerialization(ds, new BinaryFormatter());
        }

        public static long MeasureDataSetBySoapFormatter(DataSet ds)
        {
            return MeasureDataSetSerialization(ds, new SoapFormatter());
        }

        public static long MeasureDataSetSerialization(DataSet ds, IFormatter formatter)
        {
            FileInfo firstFile = new FileInfo("Test.txt");

            if (firstFile.Exists)
                firstFile.Delete();

            FileStream firstStream = firstFile.OpenWrite();

            //Try Serialize
            try
            {
                formatter.Serialize(firstStream, ds);
                firstStream.Flush();
                firstStream.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed to Serialized. Reason: " + ex.Message);
            }
            //Refresh the FileInfo
            firstFile.Refresh();
            return firstFile.Length;
        }

        static void Main(string[] args)
        {
            //Prepare the Data
            DataSet ds = new DataSet();
            Random r = new Random();
            DataTable dt = new DataTable("TestTable");
            for (int i = 1; i <= 10; i++)
            {
                dt.Columns.Add(new DataColumn("Column_" + i.ToString()));
            }
            dt.AcceptChanges();
            for (int i = 0; i < 10; i++)
            {
                DataRow dr = dt.NewRow();
                foreach (DataColumn dc in dt.Columns)
                {
                    dr[dc.ColumnName] = r.Next(int.MinValue, int.MaxValue).ToString();
                }
                dt.Rows.Add(dr);
            }
            dt.AcceptChanges();
            ds.Tables.Add(dt);
            DataSet firstDataSet = ds.Copy();           

            //Double the Size
            DataTable dt2 = dt.Copy();
            dt2.TableName = "TsetTable";
            ds.Tables.Add(dt2);
            DataSet secondDataSet = ds.Copy();

            Console.WriteLine("DataSet with One Table, measure based on XML: {0} bytes", MeasureDataSetByXML(firstDataSet));
            Console.WriteLine("DataSet with One Table, measure based on Binary Formatter: {0} bytes", MeasureDataSetByBinaryFormatter(firstDataSet));
            Console.WriteLine("DataSet with One Table, measure based on SOAP Formatter: {0} bytes", MeasureDataSetBySoapFormatter(firstDataSet));

            Console.WriteLine("DataSet with Duplicate Tables, measure based on XML: {0} bytes", MeasureDataSetByXML(secondDataSet));
            Console.WriteLine("DataSet with Duplicate Tables, measure based on Binary Formatter: {0} bytes", MeasureDataSetByBinaryFormatter(secondDataSet));
            Console.WriteLine("DataSet with Duplicate Tables, measure based on SOAP Formatter: {0} bytes", MeasureDataSetBySoapFormatter(secondDataSet));

            Console.ReadLine();
        }
    }
}
/* Execution Result: (result may varies with your own run)

DataSet with One Table, measure based on XML: 8086 bytes
DataSet with One Table, measure based on Binary Formatter: 5851 bytes
DataSet with One Table, measure based on SOAP Formatter: 9064 bytes
DataSet with Duplicate Tables, measure based on XML: 16118 bytes
DataSet with Duplicate Tables, measure based on Binary Formatter: 10823 bytes
DataSet with Duplicate Tables, measure based on SOAP Formatter: 16412 bytes

*/

 

What do you think? Which one is the closest to the actual usage of a DataSet object?
Well, I can’t say about the actual RAM usage, but if you are measuring the size of DataSet that you passed to a Web Service, my money is with MeasureDataSetBySoapFormatter

How To Determine The Size of .NET DataSet Object in Bytes

Apparently there is no way I haven’t find a way to determine the size of a .NET managed object in memory. The closest I can come out, particularly for a DataSet object is as follows:

DataSet ds = new DataSet();
// ...
// This is where you populate the content of DataSet
// ...
String xmlContent = ds.GetXml();
UnicodeEncoding uniEnc = new UnicodeEncoding();
int byteCount = uniEnc.GetByteCount(xmlContent);

But why we use UnicodeEncoding, not ASCIIEncoding, or UTF8Encoding, well, as MSDN says, String object is a collection of Unicode characters. So if we want to know how many bytes are they, we need to use UnicodeEncoding.

Of course we are still far from our actual objective, but this is a good start. I’ll update as I found other possible method.

Visual Basic 2005 Jumpstart

Today I read this book as I was waiting for my project compiling. This book has been laying on my desk since last Friday. It used to be in laying on one of my colleague desk (untouched! hehehe …. :D ). Anyway, she left my company last Friday, so she passed the book to me (Okay, I did volunteered to provide the book a space in my table :D ). I did first hesitant to receive the book as I am more fond to MSDN Class Library :D You know, just browsing here and there when you stuck at a particular problem.

 

So while my computer bogged down by the compilation process, I gave the book a peek. I skimmed through the pages looking for things that might attract my attention. Unsurprisingly (well.. I did surprised :D ), I realized that I haven’t really dig down all the knowledge (read: language features) about Visual Basic 2005. Here are the things that I learned today:

  1. AndAlso, OrElse keywords. These keywords will help you to short circuit the logic statement. Consider “foo1() AndAlso foo2()”. So if foo1() already returned false, the foo2() statement will not be evaluated. Thus, you increase the execution speed by the complexity of foo2(). And if you use OrElse, foo2() will not be evaluated if foo1() is true. Of course you cannot short circuit the logic statement if your foo2() is doing some kind of processing that you will need to use the result later on.
  2. <Obsolete(”This_Is_Your_Warning_String”)> method attribute. This method attribute helps you generate the compilation warning. So if your colleagues are using your obsolete method, they will see the warning in the compilation log or Visual Studio (Yes my friends, please look at all those warning signs before that Runtime Exception bites your honor in the production server)
  3. My namespace. There are quite many of them. You could check them out HERE. Before today, I don’t know that to download from Internet and save the content to a file can be done just by using this single line of code
    My.Computer.Network.DownloadFile _
        ("http://www.cohowinery.com/downloads/WineList.txt", _
        "C:Documents and SettingsAll UsersDocumentsWineList.txt")
    

    without all the complexity of dealing with Stream Object.

  4. And many more … (my brain short term memory capacity is limited to only three interesting things :D )

After this shocking proof of ignorance wake up call, I think I have been slowing down in my learning process. I am still far away from reaching the top. I am motivated to do better, so should you :D Have a nice reading!

 

PS:The book is good if you’re just started programming in Visual Basic.NET (or thought that you know enough about VB.NET, but apparently you’re not :D ). The flow is structured in such a way that it’s easy for you to either taking a close detailed look, or just skimming through the pages.

How To Display HTML Without Saving To File First

The following code will work with the following requirements:

  1. You are using .NET Framework 2.0
  2. You already have WebBrowser control added into your Windows Form
public void DisplayHTML(String strHTML)
{
    if (strHTML != "")
    {
         if (this.webBrowser2.Document != null)
         {
               HtmlDocument doc = this.webBrowser2.Document.OpenNew(true);
               doc.Write(strHTML);
         }
         else
         {
               this.webBrowser2.DocumentText = strHTML;
         }
     }
}

My Stream.Read() Misadventure

I was writing this small program to download a file from Internet. The original code was as follows:

            long content_lenght;
            int buffer_length = 4096;
            int read_count = 0;
            byte[] buffer;
            WebRequest req = WebRequest.Create("http://i154.photobucket.com/albums/s242/sodeve/CAP_5288Japan-Posters.jpg");
            WebResponse resp = req.GetResponse();
            FileStream output = new FileStream("output.jpg", FileMode.Create);
            Stream strm = resp.GetResponseStream();
            content_lenght = resp.ContentLength;
            while (read_count < content_lenght)
            {
                if (read_count + buffer_length > content_lenght)
                    buffer = new byte[(int)content_lenght - read_count];
                else
                    buffer = new byte[buffer_length];
                read_count += strm.Read(buffer, 0, buffer.Length);
                output.Write(buffer, 0, buffer.Length);
            }
            strm.Close();
            output.Flush();
            output.Close();

To my dismay, when the program finished its execution, the output file (output.jpg) become a scrambled image. So I thought it could be caused by the buffer size (buffer_length) that is too huge. So I reduced buffer_length from 4096 to 1024. It did worked. But when I run the program for a few more times, suddenly the image become scrambled again. What kind of problem is this?

 

Then something struck me, apparently I forgot that Internet is an unreliable medium. The bytes available inside the input buffer maybe not be as much as the number that I tried to read. Initially I have this thought that Stream.Read(…) will pause the execution thread waiting for the input buffer to have at least the number of bytes that I requested before allowing the read process to commence. So it seems the fact is contrary to what I think. Or does the waiting process only happen when we only read one single byte? So I modified my program into something like this:

            long content_lenght;
            int read_count = 0;
            WebRequest req = WebRequest.Create("http://i154.photobucket.com/albums/s242/sodeve/CAP_5288Japan-Posters.jpg");
            WebResponse resp = req.GetResponse();
            FileStream output = new FileStream("output.jpg", FileMode.Create);
            Stream strm = resp.GetResponseStream();
            content_lenght = resp.ContentLength;
            byte[] buffer= new byte[content_lenght];
            while (read_count < content_lenght)
            {
                buffer[read_count] = (byte)strm.ReadByte();
                ++read_count;
            }
            output.Write(buffer, 0, buffer.Length);
            strm.Close();
            output.Flush();
            output.Close();

It works like a charm (OOT: The statement is quite oxymoron. I mean, can anyone show me what kind of charm that scientifically proven? Okay, perhaps I should have said ‘It works as I expected’ :D ). Tragedy struck when I found out that there is even a simpler way to achieve above code’s purpose:

            WebClient wec = new WebClient();
            wec.DownloadFile("http://i154.photobucket.com/albums/s242/sodeve/CAP_5288Japan-Posters.jpg",
                  "output.jpg");

So what do you think?

Pages (8): « 1 [2] 3 4 5 » ... Last »

Close
E-mail It
Socialized through Gregarious 42