In databases, serialization is mainly done to store images.
All databases provide the feature to store images. For example:
·
IMAGE data type in MS SQL: It can hold variable length binary
data with a maximum length of 2 GB.
·
BLOB, MEDIUMBLOB and LONGBLOB in MySQL: BLOB refers to Binary
Large Objects that can store up to 64 KB of data. MEDIUMBLOB can store up to 16
MB and LONGBLOB stores up to 4 GB of binary data. BLOBs can store a variable
amount of data.
Let us consider a small table DEMO consisting of 3 columns.
Column
|
Data type
|
ID
|
INTEGER (AUTO_INCREMENT)
|
NAME
|
VARCHAR(100)
|
PHOTO
|
IMAGE (in case of MS SQL)
|
|
MEDIUMBLOB (in case of MySQL)
|
Case I (Uploading image from file)
Serializing and uploading an image on to a database is a
three step process.
1.
Create a MemoryStream object from an image file. A MemoryStream class
creates a stream in memory instead of a disk. In MemoryStream, data is stored
as an unsigned byte array that is directly accessible in memory.
2.
Serialize the MemoryStream into binary format through a BinaryFormatter.
BinaryFormatter is the class that is used to serialize and de-serialize any
object into a binary stream.
3.
Upload the bytes formed from the MemoryStream to the database. This is
achieved by a simple Insert or Update operation that is carried for any other
field in the table. The difference is that the image to be uploaded would be an
array of bytes.
NOTE: The
Listings here are based on MySQL database. The connection and command objects
used here belong to the namespace MySql.Data.MySqlClient. This is found from
the MySQL .NET
Connector which is an ADO.NET driver for MySQL.
The Listing below consists of two functions.
SerializeNSaveToDB()
This function first creates an Image object from a file and
serializes it into a MemoryStream. It then calls the Call_Upload_Object()
function to save the serialized object to the database.
Call_Upload_Object(string query, byte[]
image, string column)
It takes three arguments, the query, an array of bytes that
is the serialized object, in this case the image, and the column name (used in
the Query). It then performs the necessary database operation with the help of
the classes provided by the MySQL .NET Connector.
Listing 1: Serialization of Image from file
using MySql.Data.MySqlClient;
private string imagePath = string.Empty;
private string MySqlConnString =
"Server = localhost; Uid = root; Pwd = password;
Database = demo;";
private void SerializeNSaveToDB()
{
MemoryStream str = new MemoryStream();
try
{
string column = "?IMAGE ";
Image img = Image.FromFile(imagePath);
BinaryFormatter oBFormatter = new BinaryFormatter();
oBFormatter.Serialize(str, img);
byte[]oSerializedImg = str.ToArray();
string Query = "INSERT INTO DEMO (NAME, PHOTO) VALUES('Image 1', ? IMAGE)
";Call_Upload_Object(Query, oSerializedImg, column);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
str.Close();
}
}
private void Call_Upload_Object(string query, byte[]image, string column)
{
MySqlConnection oMySqlConnection = new MySqlConnection(MySqlConnString);
try
{
MySqlCommand oMySqlCommand = new MySqlCommand();
oMySqlConnection.Open();
oMySqlCommand.Connection = oMySqlConnection;
oMySqlCommand.CommandText = query;
oMySqlCommand.Parameters.Add(column, image);
oMySqlCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
oMySqlConnection.Close();
}
}
Case II (Downloading an image from Database)
This is also a three step process.
1.
First, the image is fetched into a byte array and is then converted into
a stream like MemoryStream or FileStream.
2.
The stream of bytes is now de-serialized by using a BinaryFormatter.
3.
This Stream is then either written to a file or can be directly
displayed in a PictureBox.
Listing 2 consists of a single function.
DeserializeNSaveToFile()
This function fetches the serialized image from the database
with the help of MySqlClient Classes. This object is converted into a MemoryStream
object which is then de-serialized with the help of a BinaryFormatter. This is
in turn converted into an Image and can be easily stored into a file or can be
directly displayed by a PictureBox in our application.
Listing 2: De-serialization of Image from Database
private void DeserializeNSaveToFile()
{
DataTable ds = new DataTable();
MySqlConnection oMySqlConn = new MySqlConnection(MySqlConnString);
try
{
string Query = "SELECT * FROM DEMO";
MySqlCommand cmd = new MySqlCommand(Query, oMySqlConn);
oMySqlConn.Open();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(ds);
MemoryStream oStr = new MemoryStream((byte[])ds.Rows[0]["PHOTO"]);
BinaryFormatter oBFormatter = new BinaryFormatter();
Image img = (Image)oBFormatter.Deserialize(oStr);
img.Save("C:\\demo_image.jpg", ImageFormat.Jpeg);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
oMySqlConn.Close();
}
}