Roberto Sánchez - Programador .NET/C++

Serialización.

La mayoría de las aplicaciones basan su funcionalidad en el tratamiento de datos en diferentes formatos, bien sean datos obtenidos de terceros o bien datos generados y consumidos por la propia aplicación. Son varias las maneras para tratar datos, siendo las bases de datos la fórmula más productiva. .NET ofrece clases para el tratamiento de datos de diferentes motores de bases de datos, como SQL Server, Oracle, o SQLite.

Sin embargo, en ocasiones tendrás que hacer tratamientos de datos de volumen reducido, y en esas ocasiones las bases de datos se te quedarán grandes y el sistema no será muy productivo. Para el manejo de datos de volúmenes reducidos la opción más productiva es la serialización. Pero además, la serialización no es solamente útil para el tratamiento de datos de pequeño volumen, sino que permite la conservación en el disco de objetos previamente instanciados para su posterior recuperación, o el envío de estos objetos a través de red para ser consumidos por otra aplicación.

Debes tener muy claro que la serialización se efectúa sobre objetos instanciados a partir de, por ejemplo, una clase, es decir, la serialización se produce en el objeto, no en la clase; la clase sigue estando allí, en el código fuente, no es más que el molde del objeto instanciado a partir de ella. Son los objetos de esa clase los que se pueden serializar.

Existen dos tipos de serialización: la serialización binaria y la serialización XML:

- La serialización binaria permite la creación de una copia exacta del objeto serializado. Todos sus miembros públicos y privados de su clase, incluso su ensamblado, son serializados.

- La serialización XML crea una representación únicamente de los miembros públicos. Su ventaja es que permite establecer una comunicación más sencilla entre aplicaciones heterogéneas.

Serialización binaria.

La utilidad más importante de la serialización binaria es la posibilidad de guardar el estado de un objeto para poder volver a crearlo de manera idéntica más tarde. Para poder serializar un objeto, previamente debes marcar la clase con un atributo serializable, ya que si no lo haces, el intento de serialización producirá una excepción:

[Serializable]
public class SerializableClass
{
    public string Name;
    public string Surname;
}

Ahora podemos serializar un objeto creado a partir de la clase 'SerializableClass'. Lo haremos de la siguiente manera: primero creamos un objeto de la clase llamado 'serializableClass' y establecemos valores en las propiedades de ese objeto. Después, a través de un flujo de archivo, serializaremos el objeto para su conservación en el disco:

SerializableClass serializableClass = new SerializableClass();
serializableClass.Name = "Nombre";
serializableClass.Surname = "Apellido";
// Creación del constructor binario.
IFormatter formatter = new BinaryFormatter();
// Flujo del archivo.
Stream stream = new FileStream("C:\SerializableClass.bin", FileMode.Create);
// Serialización del objeto.
formatter.Serialize(stream, serializableClass);
// Cierre del archivo y liberación de recursos.
stream.Close();
stream.Dispose();

El resultado ha sido la creación en el disco duro de un archivo llamado 'SerializableClass.bin' que contiene todas y cada una de las características del objeto creado a partir de la clase 'SerializableClass'. Ahora estamos en disposición de realizar la deserialización y obtener una copia exacta del objeto:

// Creación del constructor binario.
IFormatter formatter = new BinaryFormatter();
// Flujo del archivo.
Stream stream = new FileStream("C:\SerializableClass.bin", FileMode.Open);
// Deserialización del objeto.
SerializableClass copy = (SerializableClass)formatter.Deserialize(stream);
// Cierre del archivo y liberación de recursos.
stream.Close();
stream.Dispose();

Así de fácil. Ahora, el objeto 'copy' será idéntico al objeto 'serializableClass' que fue previamente serializado y escrito en el disco. Podremos utilizarlo y comprobar que los valores de sus propiedades se han mantenido intactos. Observa que es imprescindible cerrar el archivo después de su escritura y su lectura, y liberar los recursos del flujo de archivo llamando al método 'Dispose()', pues de otra forma el archivo no se cerrará y podrá producir excepciones no controladas cuando intentes acceder a él posteriormente.

Serialización XML.

A diferencia de la serialización binaria, la serialización XML sólo se realiza sobre los miembros públicos del objeto serializado. Esto permite una gran compatibilidad a la hora de serializar un objeto que vaya a ser consumido por otra aplicación. Otra diferencia es que no será necesario marcar la clase con el atributos serializable:

public class SerializableClass
{
    public string Name;
    public string Surname;
}

Procedemos a la creación y serialización del objeto:

SerializableClass serializableClass = new SerializableClass();
serializableClass.Name = "Nombre";
serializableClass.Surname = "Apellido";
// Creación del serializador XML.
XmlSerializer serializerXML = new XmlSerializer(typeof(SerializableClass));
// Flujo del archivo.
Stream stream = new FileStream("C:\SerializableClass.xml", FileMode.Create);
// Serialización del objeto.
serializerXML.Serialize(stream, serializableClass);
// Cierre del archivo y liberación de recursos.
stream.Close();
stream.Dispose();

El proceso es casi el mismo, también muy sencillo. El resultado será un archivo de formato XML que contendrá los miembros públicos del objeto, pero sólo los miembros públicos.

La deserialización se realizará de la misma manera:

// Creación del serializador XML.
XmlSerializer serializerXML = new XmlSerializer(typeof(SerializableClass));
// Flujo del archivo.
Stream stream = new FileStream("C:\SerializableClass.xml", FileMode.Open);
// Deserialización del objeto.
SerializableClass copy = (SerializableClass)serializerXML.Deserialize(stream);
// Cierre del archivo y liberación de recursos.
stream.Close();
stream.Dispose();