Serialization and deserialization are often heard and used, but some may not know :. net. net frameword how to implement such a mechanism for us, here I also briefly talk about some of my understanding of serialization and deserialization.
1. What serialization and deserialization
SerializationGenerally speaking, an object is converted into a byte stream, which can be easily stored in a disk file or database.DeserializationIt is the deserialization inverse process, that is, the process of transferring a byte back to the original object.
But why is serialization and deserialization required? This problem also involves the use of serialization and deserialization,
The main functions of serialization include:
- ApplyProgramIs saved in a disk file or database and restored when the application is run next time. For example, Asp.net uses serialization and deserialization to save and restore session states.
- A group of objects can be easily copied to the clipboard of Windows Forms, and pasted back to the same or another application.
- Send an object from one application domain to another by value
If you serialize an object into a byte stream in the memory, you can use other technologies to process data, such as encrypting and compressing data.
Ii. simple use of serialization and deserialization
. NET Framework provides two serialization methods:
- Binary serialization
- XML and soap serialization
Simple use of serialization and deserialization:
Using system; using system. io; using system. runtime. serialization. formatters. binary; namespace serializable {[serializable] public class person {Public String personname; [nonserialized] Public String personheight; private int personage; Public int personage {get {return personage ;} set {personage = value ;}} public void write () {console. writeline ("person name:" + personname); console. writeline ("person Height:" + personheight); console. writeline ("person age:" + personage) ;}} class program {static void main (string [] ARGs) {person = new person (); person. personname = "Jerry"; person. personheight = "175"; person. personage = 22; stream = serialize (person); // reset stream for demonstration. position = 0; person = NULL; person = deserialize (Stream); person. write (); console. read ();} Private Static memorystream serialize (person) {memorystream stream = new memorystream (); // construct the binary serialization formatter binaryformatter = new binaryformatter (); // tells the serializer to serialize the object to a stream in binaryformatter. serialize (stream, person); Return stream;} Private Static person deserialize (Stream stream) {binaryformatter = new binaryformatter (); Return (person) binaryformatter. deserialize (Stream );}}}
It mainly calls the binnaryformatter class in the system. runtime. serialization. formatters. Binary namespace for serialization and deserialization. It calls the deserialization result:
It can be seen that all other Members marked with nonserialized can be serialized. Note that this attribute can only be applied to a field of the type and will be inherited by the derived type.
The serialization and deserialization of soap and XML are similar to the above. You only need to change the formatter. I will not list it here.
Iii. Control serialization and deserialization
There are two methods to control serialization and deserialization:
- Attributes such as onserializing, onserialized, ondeserializing, ondeserialized, nonserialized, and optionalfield
- Implement the system. runtime. serialization. iserializable Interface
Method 1: Control serialization and deserializationCode:
Using system; using system. io; using system. runtime. serialization; using system. runtime. serialization. formatters. binary; namespace controlserialization {[serializable] public class circle {private double radius; // radius [nonserialized] public double area; // area public circle (double inputradiu) {radius = inputradiu; area = math. pI * radius;} [ondeserialized] private void ondeserialized (streaming Context context) {area = math. pI * radius;} public void write () {console. writeline ("radius is:" + radius); console. writeline ("area is:" + area) ;}} class program {static void main (string [] ARGs) {Circle C = new circle (10 ); memorystream stream = new memorystream (); binaryformatter formatter = new binaryformatter (); // serialize the object to the memory stream. Here you can use system. io. an object of any type derived from the stream abstract class. Here I use memory Stream type. Formatter. serialize (stream, c); stream. position = 0; C = NULL; C = (circle) formatter. deserialize (Stream); C. write (); console. read ();}}}
The running result is:
Note:: If you comment outOndeserializedAttribute, the value of the area field is 0, because the area field is not serialized into the stream.
In the object to be serialized above, the formatter only serializes the value of the radius field of the object. The value in the area field is not serialized, because the nonserializedattricle attribute has been applied to this field. Then, when we construct a circle object using the code like Circle C = new circle (10, area sets a value about 314.159. When this object is serialized, only the value of the radius field (10) is written into the stream, but when it is deserialized into a circle object, the value of the "area" field is initialized to 0 instead of a value of about 314.159. To solve this problem, you can customize a method application.OndeserializedattributeAttribute. At this time, the execution process is: every time an instance of the deserialization type is executed, the formatter checks whether a method that applies the attribute is defined in the type. If yes, the method is called, when this method is called, all serializable fields are correctly set. BesidesOndeserializedattributeThis custom attribute, the system. runtime. serialization namespace also definesOnserializingattribute, onserializedattributeAndOndeserializingattributeThese custom attributes.
ImplementationIserializableControl the serialization and deserialization code through the interface:
Using system; using system. io; using system. runtime. serialization; using system. runtime. serialization. formatters. binary; using system. security. permissions; namespace controlserilization2 {[serializable] public class myobject: iserializable {public int N1; Public intn2;
[Nonserialized]
Public String STR; Public myobject () {} protected myobject (serializationinfo info, streamingcontext context) {n1 = info. getint32 ("I"); N2 = info. getint32 ("J"); STR = info. getstring ("K");} [securitypermissionattribute (securityaction. demand, serializationformatter = true)] Public Virtual void getobjectdata (serializationinfo info, streamingcontext context) {info. addvalue ("I", N1); info. addvalue ("J ", N2); info. addvalue ("K", STR);} public void write () {console. writeline ("N1 is:" + N1); console. writeline ("N2 is:" + N2); console. writeline ("STR is:" + Str) ;}} class program {static void main (string [] ARGs) {myobject OBJ = new myobject (); obj. n1 = 2; obj. n2 = 3; obj. STR = "Jeffy"; memorystream stream = new memorystream (); binaryformatter formatter = new binaryformatter (); // serialize the object to the memory stream, Here, we can use an object of any type derived from the system. Io. Stream abstract class. Here we use the memorystream type. Formatter. serialize (stream, OBJ); stream. position = 0; OBJ = NULL; OBJ = (myobject) formatter. deserialize (Stream); obj. write (); console. read ();}}}
Result:
The execution process is as follows: when the formatter serializes an object, it checks each object. If the type of an object is realizedIserializableInterface, The formatter ignores all the Custom Attributes and creates a newSystem. runtime. serialization. serializationinfoObject. This object contains a set of values to be actually serialized. After the serializationinfo object is constructed and initializedGetobjectdataAnd passSerializationinfoObject reference,GetobjectdataThe method determines which information is needed to serialize the object and add the informationSerializationinfoIn the object, add each required data by calling the addvalue method. After all necessary serialization information is added, it will be returned to the formatter, and then the formatter obtains the information that has been added toSerializationinfoAll values in the object and serialize them to the stream. When deserializing an object from the stream, the formatter allocates memory for the new object. Initially, all fields of this object are set to 0 or null. Then, the formatter checks whether the type is implemented.IserializableInterface. If this interface exists, the formatter tries to call a special constructor. Its Parameters andGetobjectdataThe methods are completely consistent.
Iv. How to serialize and deserialize The formatter
From the analysis above, we can see that the formatter is working mainly for serialization and deserialization. However, the following is to explain how the formatter serializes an application.SerializableattributeAttribute object.
- Formatter callFormatterservicesOfGetserializablemembersMethod: public static memberinfo [] getserializablemembers (type, streamingcontext context); this method obtains Public and Private implementation fields (markedNonserializedattributeeAttribute fields ). Method returns an array composed of memberinfo objects. Each element corresponds to a serializable instance field.
- Object serialized,System. reflection. memberinfoObject array passedFormatterservicesStatic MethodGetobjectdata: Public static object [] getobjectdata (Object OBJ, memberinfo [] members); this method returnsObjectArray. Each element identifies the value of a field in the serialized object.
- The formatter writes the complete name of the Assembly identifier and type to the stream.
- The formatter then traverses the elements in the two arrays and writes the names and values of each member to the stream.
The next step is to explain how the formatter automatically deserializes an application.SerializableattributeAttribute object.
- The formatter reads the Assembly ID and complete type name from the stream.
- Formatter callFormatterservicesStatic MethodGetuninitializedobject: Public static object getuninitializedobject (type tType); this method allocates memory for a new object, but does not call the constructor for the object. However, all fields of the object are initialized to 0 or null.
- The formatter constructs and initializesMemberinfoArray, callFormatterservicesOfGetserializablemembersMethod. This method returns a set of fields that are serialized and need to be deserialized.
- The formatter creates and initializesObjectArray.
- The newly assigned object,MemberinfoArray and ParallelismObjectArray reference to passFormatterservicesStatic MethodPopulateobjectmembers:
Public static object populateobjectmembers (Object OBJ, memberinfo [] members, object [] data); this method traverses the array and initializes each field to a corresponding value.
Note: part of how to serialize and deserialize objects in formatting is taken from CLR via C # (Third edition), which allows beginners to further understand what the formatter is doing during serialization and deserialization.
This article describes serialization and deserialization.ArticleFinally, I hope to help myself with my future review and friends in the garden.
Author: learnig hard Source: http://www.cnblogs.com/zhili/ this article copyright belong to the author and blog Park, welcome to reprint, but without the author's consent must retain this paragraph of the statement, and in the Article Page clearly given the original connection, otherwise, you are entitled to pursue legal liability.
Logistics Distribution Network http://wlphw.com/QQ online: 471226865