|
Serialisation
is the process of writing objects on a persistent storage
media such as a file on the disk. Complementary to serialisation
is deserialisation using which we can restore objects. Lets
take a look at an example where we have used serialisation
and deserialisation to store and retrieve objects of a class
to/from a file.
The User-Interface of the application is given in the following
screen shot:

This application enables the user to collect information of
students who wish to apply to a college and store their information
in a file called student.dat in the form of objects of the
student class. We have used textboxes to collect the information
such as the name of the student in a textbox named sname,
the address of the student in a textbox named sadd, the field
in which he wants to do his major in a textbox named smaj
and his age in a textbox named sage. To uniquely identify
a students application we have provided an application
number to each applicant, which would get displayed in a label
named lappnum and would get incremented every time the user
adds information of a new applicant. As soon as the user clicks
on the Apply button named apply, the data would
get serialised in the student.dat file.
The application also provides the user with a facility through
which he can retrieve the information of any particular student
back from the student.dat file and display it. The user needs
to supply the application number in the textbox named tappnum
and click on the Look Up button called lookup.
As soon as he clicks the button, the information of that particular
student gets displayed in a message box.
To be able to serialise or deserialise objects of the student
class, we need to attach the [Serializable] attribute to the
class, which indicates that objects of the class can be serialised
and deserialised. The student class is given below:
[Serializable]
class student
{
int appnum;
string name;
string address;
string major;
int age;
public student (int ap, string n, string ad, string m, int ag)
{
appnum = ap;
name = n;
address = ad;
major = m;
age = ag ;
}
public override string ToString()
{
string s = Application Number: +appnum.ToString( ) + \n;
s += Name: + name + \n;
s += Address: + address + \n;
s += Major: + major + \n;
s += Age: + age.ToString( );
return s;
}
}
Here we have added relevant data members to the class representing
the information of the student. The five-argument constructor
is used to initialise the data members and the overridden
method ToString( ) is used to generate a display string of
any instance on which the method is called.
We have created an array of this class in our Form1 class.
We also added an integer data called appnum that would keep
track of the application number of each student, a reference
of the FileInfo class and a reference of the BinaryFormatter
class as data members of the Form1 class as shown below:
student[] stu = new student[20];
int appnum = 1;
FileInfo f;
BinaryFormatter b;
We added the following code to the constructor of the Form1
class after the call to the InitializeComponent( ) method.
lsappnum.Text = appnum.ToString();
f = new FileInfo(C:\\student.dat);
b = new BinaryFormatter();
Here we have first set the label displaying the application
number to appnum. Next we have created a FileInfo object and
stored its reference in f. To be able to create an object
of the FileInfo class we need to add using System.IO at the
beginning of the program. Then we have created an object of
the BinaryFormatter and stored its reference in b. This object
would be used to serialise and deserialise data. For this
we need to add the statement using System.Runtime.Serialization.Formatters.Binary;
When the user enters student information in the textboxes
and clicks on the apply button, the following handler gets
called:
private void apply_Click(object sender, System.EventArgs e)
{
int ap = int.Parse(lsappnum.Text);
string n = sname.Text;
string ad = sadd.Text;
string m = smaj.Text;
int ag = int.Parse(sage.Text);
student s = new student(ap, n, ad, m, ag);
Stream sw = f.Open(FileMode.Append, FileAccess.Write);
b.Serialize(sw,s);
sw.Close();
appnum ++ ;
lsappnum.Text = appnum.ToString();
sname.Clear();
sadd.Clear();
smaj.Clear();
sage.Clear();
}
Here we have first collected the information in local variables
and created an object of the student class by passing the
values to the constructor of the student class. Next we have
opened the file referred to by f with the FileMode as Append
because we wish to append the file with the current student
at the end of the file, and the FileAccess as Write because
we will be writing to the file. We have collected the reference
of the Stream object returned by the Open( ) method in sw.
Next we have called the Serialize( ) method of the BinaryFormatter
class and passed the Stream reference to it along with the
object that we wish to serialise. After serialising the object
we have closed the stream. Next we have incremented the value
of appnum by 1 and set the text of the label to the incremented
value. Lastly we have cleared all the textboxes so that the
user can enter information of another student.
Now if the user wishes to retrieve the information of any
user, he needs to supply the application number of the student
and click on the lookup button. On doing so the following
handler would get called:
private void lookup_Click(object sender, System.EventArgs e)
{
int app = int.Parse(tsappnum.Text);
Stream sr = f.Open(FileMode.Open, FileAccess.Read);
int i = 0;
while (sr.Position != sr.Length)
{
stu[i] = (student) b.Deserialize(sr);
i++;
}
string str = stu[app-1].ToString();
MessageBox.Show(str);
sr.Close();
}
Here
we have first collected the application number of the student
whose information we wish to retrieve in a local variable
called app. Next we have opened the student.dat file again
with the FileMode as Open and FileAccess as Read and collected
the stream returned in a reference called sr. The Position
property of the Stream class indicates the current position
within the stream and the Length property indicates the total
length of the stream. We have used these two properties in
a while loop and deserialised all the objects in the array
referred by stu. Now it is very easy to retrieve the instance
of the student requested by the user from the array, i.e.
it would be the same instance present at the index app-1 in
the array. Next we have called the overridden ToString() method
on that instance and displayed the string in the message box.
Lastly we have closed the stream.
There is a drawback in the application in that as soon as
we execute the program for the second time, the application
number is set to 1. To overcome this, we can store the application
number in the registry and set the application number to the
value in the registry every time we execute the application.
 |
Yashavant
Kanetkar, one of the first Express Computer columnists,
is an established software expert, speaker and author
with several best-sellers to his credit, including titles
like “Let Us C” and the “Fundas” series. Contact him at
kanet@nagpur.dot.net.in |
|