#pragma once
namespace CarReview
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::IO;
---------------------------------------------------System::Void btnWrite_Click(System::Object^ sender, System::EventArgs^ e) { String ^ Make = txtMake->Text; String ^ Model = txtModel->Text; int Year = int::Parse(txtYear->Text); String ^ Color = txtColor->Text; FileStream ^ stmCar = gcnew FileStream("Car1.car", FileMode::Create); BinaryWriter ^ bnwCar = gcnew BinaryWriter(stmCar); try { bnwCar->Write(Make); bnwCar->Write(Model); bnwCar->Write(Year); bnwCar->Write(Color); } finally { bnwCar->Close(); stmCar->Close(); } }
Here is an example of running the program:
This is an example of the techniques used in file
processing to save individual data of primitive types:
The values can be retrieved with the following code:
System::Void btnRead_Click(System::Object^ sender, System::EventArgs^ e) { FileStream ^ stmCar = gcnew FileStream("Car1.car", FileMode::Open); BinaryReader ^ bnrCar = gcnew BinaryReader(stmCar); try { txtMake->Text = bnrCar->ReadString(); txtModel->Text = bnrCar->ReadString(); txtYear->Text = bnrCar->ReadUInt32().ToString(); txtColor->Text = bnrCar->ReadString(); } finally { bnrCar->Close(); stmCar->Close(); } }
In the same way, you can save the individual fields of
a class or you can retrieve the individual fields of a car:
Here is an example:
ref class CCar { public: String ^ Make; String ^ Model; int Year; String ^ Color; }; private: System::Void btnWrite_Click(System::Object^ sender, System::EventArgs^ e) { CCar ^ vehicle = gcnew CCar; vehicle->Make = txtMake->Text; vehicle->Model = txtModel->Text; vehicle->Year = int::Parse(txtYear->Text); vehicle->Color = txtColor->Text; FileStream ^ stmCar = gcnew FileStream("Car2.car", FileMode::Create); BinaryWriter ^ bnwCar = gcnew BinaryWriter(stmCar); try { bnwCar->Write(vehicle->Make); bnwCar->Write(vehicle->Model); bnwCar->Write(vehicle->Year); bnwCar->Write(vehicle->Color); } finally { bnwCar->Close(); stmCar->Close(); } } System::Void btnRead_Click(System::Object^ sender, System::EventArgs^ e) { FileStream ^ stmCar = gcnew FileStream("Car2.car", FileMode::Open); BinaryReader ^ bnrCar = gcnew BinaryReader(stmCar); try { CCar ^ vehicle = gcnew CCar; vehicle->Make = bnrCar->ReadString(); vehicle->Model = bnrCar->ReadString(); vehicle->Year = bnrCar->ReadUInt32(); vehicle->Color = bnrCar->ReadString(); txtMake->Text = vehicle->Make; txtModel->Text = vehicle->Model; txtYear->Text = vehicle->Year.ToString(); txtColor->Text = vehicle->Color; } finally { bnrCar->Close(); stmCar->Close(); } } }; }
When it comes to a class, the problem with saving
individual fields is that you could forget to save one of the fields. For
example, considering a CCar class, if you don't save the Make information
of a CCar object and retrieve or open the saved object on another
computer, the receiving user would miss some information and the car
cannot be completely identifiable. An alternative is to save the whole
CCar object.
Object serialization consists of saving a whole object
as one instead of its individual fields:
In other words, a variable declared from a class can
be saved to a stream and then the saved object can be retrieved later or
on another computer. The .NET Framework supports two types of object
serialization: binary and SOAP.
Binary serialization works by processing an object
rather than streaming its individual member variables. This means that, to
use it, you define an object and initialize it, or "fill" it, with the
necessary values and any information you judge necessary. This creates a
"state" of the object. It is this state that you prepare to serialize.
When you save the object, it is converted into a stream.
To perform binary serialization, there are a few steps
you must follow. When creating the class whose objects would be
serialized, start it with the [Serializable] attribute. Here is an
example:
[Serializable]
public ref class CCar
{
public:
String ^ Make;
String ^ Model;
int Year;
String ^ Color;
};
Before serializing an object, you should reference the
System::Runtime::Serialization::Formatters::Binary namespace. The
class responsible for binary serialization is called BinaryFormatter.
This class is equipped with two constructors. The default constructor is
used to simply create an object.
After declaring the variable, to actually serialize an
object, call the Serialize() member function of the
BinaryFormatter class. The member function is overloaded with two
versions. One of the versions of this member function uses the following
syntax:
public: virtual void Serialize(Stream^ serializationStream, Object^ graph) sealed;
The first argument to this member function must be an
object of a Stream-based class, such as a FileStream object.
The second argument must be the object to serialize. This means that,
before calling this member function, you should have built the object.
Here is an example:
#pragma once
namespace CarReview {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::IO;
using namespace System::Runtime::Serialization::Formatters::Binary;
[Serializable]
ref class CCar
{
public:
String ^ Make;
String ^ Model;
int Year;
String ^ Color;
};
--------------------------------------------------------------------System::Void btnWrite_Click(System::Object^ sender, System::EventArgs^ e) { CCar ^ vehicle = gcnew CCar; vehicle->Make = txtMake->Text; vehicle->Model = txtModel->Text; vehicle->Year = int::Parse(txtYear->Text); vehicle->Color = txtColor->Text; FileStream ^ stmCar = gcnew FileStream("Car3.car", FileMode::Create); BinaryFormatter ^ bfmCar = gcnew BinaryFormatter; bfmCar->Serialize(stmCar, vehicle); }
As serialization is the process of storing an object
to a medium, the opposite, serialization is used to retrieve an object
from a stream. To support this, the BinaryFormatter class is
equipped with the Deserialize() member function. Like
Serialize(), the Deserialize() member function is overloaded
with two versions. One of them uses the following syntax:
public: virtual Object^ Deserialize(Stream^ serializationStream) sealed;
This member function takes as argument a Stream-based
object, such as a FileStream variable, that indicates where the
file is located. The Deserialize() member function returns an
Object object. As a goal, you want the Deserialize() member
function to produce the type of object that was saved so you can retrieve
the values that the returned object holds. Because the member function
returns an Object value, you must cast the returned value to the
type of your class.
Once the Deserialize() member function has
returned the desired object, you can access its values. Here is an
example:
System::Void btnRead_Click(System::Object^ sender, System::EventArgs^ e) { FileStream ^ stmCar = gcnew FileStream("Car3.car", FileMode::Open); BinaryFormatter ^ bfmCar = gcnew BinaryFormatter; CCar ^ vehicle = (CCar ^)bfmCar->Deserialize(stmCar); txtMake->Text = vehicle->Make; txtModel->Text = vehicle->Model; txtYear->Text = vehicle->Year.ToString(); txtColor->Text = vehicle->Color; }
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The .NET Framework supports another technique of
serialization referred to as SOAP (which stands for Simple Object Access
Protocol). This technique is related to XML but, although we haven't studied
XML, you don't need to know anything about it to use SOAP serialization.
To serialize an object using SOAP, you follow the same
steps we reviewed for the binary serialization with one addition: you must
add a certain reference.
When creating the class whose objects would be
serialized, mark it with the [Serializable] attribute. Here is an
example:
[Serializable]
public ref class CCar
{
public:
String ^ Make;
String ^ Model;
int Year;
String ^ Color;
};
To support SOAP serialization, the .NET Framework
provides the SoapFormatter class. This class is defined in the
System::Runtime::Serialization::Formatters::Soap namespace that is part
of the System.Runtime.Serialization.Formatters.Soap.dll library. In
order to use The SoapFormatter class, you must reference this
assembly. You can create an object and initialize it as you see fit. Before
saving it, as always, create a Stream-based object that would
indicate the name (and location) of the file and the type of action to
perform. Then, declare a SoapFormatter variable using its default
constructor. To actually save the object, call the Serialize() member
function of this class. This member function uses the same syntax as that of
the BinaryFormatter class: it takes two arguments. The first is a
Stream-based object. The second is the object that needs to
be serialized.
De-serialization in soap is performed exactly as done
for the binary de-serialization. To support it, the SoapFormatter
class is equipped with the Deserialize() member function. This member
function uses the same syntax as its equivalent of the BinaryFormatter
class. The approach to use it is also the same.
In the examples we have used so far, we were saving the
whole object. You can make it possible to save only some parts of the class.
When creating a class, you can specify what fields would be serialized and
which ones would not be. To specify that a member cannot be saved, you can
mark it with the [NonSerialized] attribute. Here is an example:
[Serializable]
public ref class CVoiture
{
public:
String ^ Make;
String ^ Model;
// Because the value of a car can change,
// there is no reason to save it
[NonSerialized]
double Value;
unsigned int Year;
String ^ Color;
};
After creating the class, you can declare a variable of
it and serialize it, using either the binary or the SOAP approach. You can
then retrieve the object and its values, using any of the techniques we
learned earlier.
To support serialization, the .NET Framework provides
the ISerializable interface. You can create a class that implements
this interface to customize the serialization process. Even if you plan to
use this interface, the class you create must be marked with the
[Serializable] attribute.
The .NET Framework is filled with many classes ready for
serialization. To know that a class is ready for serialization, when viewing
its documentation either in the MSDN web site or in the help documentation,
check that it is marked with the [SerializableAttribute]. Some of the
classes provide the properties and member functions to create an object and
directly save it. For some other classes, you must first create a class,
mark it with the [Serializable] attribute, build an object of it, and
then pass it to the .NET class.
Sumber : http://www.functionx.com/vccli/fileprocessing/serialization.htm
|