24 junio, 2007

Serialización Xml

Este formato es basado en XML y es recomendado cuando el objeto será des-serializado en diferentes plataformas o cuando va a ser trasportado por la red siempre y cuando no se requiera serializar miembros privados. Este formato brinda una gran interoperabilidad y es muy fácil de comprender.

'Persona.vb

Public Class Persona

Public Nombre As String

Public Apellido As String

Public Edad As Integer

Public Sub New()

MyBase.New()

End Sub

Public Sub New(ByVal _nombre As String, ByVal _apellido As String, ByVal _edad As String)

Nombre = _nombre

Apellido = _apellido

Edad = _edad

End Sub

End Class

'Serialize.vb

Imports System.IO

Imports System.Runtime.Serialization

Imports System.Xml.Serialization

Module Module1

Sub Main()

Dim Manuel As New Persona("Manuel", "Salas", 30)

Dim archivo As New FileStream("c:\temp\f_persona.xml", FileMode.Create)

Dim formateador As New XmlSerializer(GetType(Persona))

formateador.Serialize(archivo, Manuel)

archivo.Close()

End Sub

End Module

Como podemos observar es muy similar a las serializaciones anteriores, básicamente seguimos los mismos tres pasos:

  1. Instanciamos un FileStream para almacenar el objeto serializado.
  2. Instanciamos un Formateador para serializar el objeto.
  3. Serializamos el objeto llamando al método serialize del formateador.

Para des-serializar un objeto seguimos los mismos pasos de manera inversa:

  1. Instanciamos un FileStream para leer el objeto serializado.
  2. Instanciamos un Formateador para des-serializar el objeto.
  3. Des-serializamos el objeto llamando al método deserialize del formateador.

Veamos como des-serializar el objeto que serializamos en el fragmento de código anterior:

'Persona.vb

Public Class Persona

Public Nombre As String

Public Apellido As String

Public Edad As Integer

Public Sub New()

MyBase.New()

End Sub

Public Sub New(ByVal _nombre As String, ByVal _apellido As String, ByVal _edad As String)

Nombre = _nombre

Apellido = _apellido

Edad = _edad

End Sub

End Class

'Deserialize.vb

Imports System.IO

Imports System.Runtime.Serialization

Imports System.Xml.Serialization

Module Module1

Sub Main()

Dim Manuel As New Persona

Dim archivo As New FileStream("c:\temp\f_persona.xml", FileMode.Open)

Dim formateador As New XmlSerializer(GetType(Persona))

Manuel = formateador.Deserialize(archivo)

archivo.Close()

Console.WriteLine("Nombre ={0}, Apellido = {1}, Edad = {2}", Manuel.Nombre, Manuel.Apellido, Manuel.Edad)

Console.ReadKey()

End Sub

End Module

20 junio, 2007

Serialización SOAP

Esta serialización es basado en XML y es recomendado cuando el objeto será des-serializado en diferentes plataformas o cuando va a ser trasportado por la red. Los objetos serializados con este formato pueden ser tres o cuatro veces más grandes que los serializados mediante el formato binario. Serialicemos un objeto mediante el formato SOAP en un archivo para su posterior recuperación:

Imports System.IO

Imports System.Runtime.Serialization

Imports System.Runtime.Serialization.Formatters.Soap

Module Module1

<System.Serializable()> Public Class Persona

Public Nombre As String

Public Apellido As String

Public Edad As Integer

End Class

Sub Main()

Dim Manuel As New Persona()

Manuel.Apellido = "Salas"

Manuel.Nombre = "Manuel"

Manuel.Edad = 30

Dim archivo As New FileStream("c:\temp\f_persona.xml", FileMode.Create)

Dim formateador As New SoapFormatter

formateador.Serialize(archivo, Manuel)

archivo.Close()

End Sub

End Module

Como podemos observar básicamente son tres pasos los que debemos realizar para serializar un objeto:

  1. Instanciamos un FileStream para almacenar el objeto serializado.
  2. Instanciamos un Formateador para serializar el objeto (Es necesario agregar una referencia a "System.Runtime.Serialization.Formatters.Soap.dll").
  3. Serializamos el objeto llamando al método serialize del formateador.

Para des-serializar un objeto seguimos los mismos pasos de manera inversa:

  1. Instanciamos un FileStream para leer el objeto serializado.
  2. Instanciamos un Formateador para des-serializar el objeto.
  3. Des-serializamos el objeto llamando al método deserialize del formateador.

Veamos como des-serializar el objeto que serializamos en el fragmento de código anterior:

Imports System.IO

Imports System.Runtime.Serialization

Imports System.Runtime.Serialization.Formatters

Module Module1

<System.Serializable()> Public Class Persona

Public Nombre As String

Public Apellido As String

Public Edad As Integer

End Class

Sub Main()

Dim Manuel As New Persona()

Dim archivo As New FileStream("c:\temp\f_persona.xml", FileMode.Open)

Dim formateador As New Soap.SoapFormatter

Manuel = formateador.Deserialize(archivo)

archivo.Close()

Console.WriteLine("Nombre ={0}, Apellido = {1}, Edad = {2}", Manuel.Nombre, Manuel.Apellido, Manuel.Edad)

Console.ReadKey()

End Sub

End Module

14 junio, 2007

Serialización Binaria

La serialización binaria es muy eficiente, pero recomendado cuando el objeto serializado va a ser des-serializados solo en aplicaciones dot.net. Serialicemos un objeto en un archivo para su posterior recuperación:

Imports System.IO

Imports System.Runtime.Serialization

Imports System.Runtime.Serialization.Formatters

Module Module1

<System.Serializable()> Public Class Persona

Public Nombre As String

Public Apellido As String

Public Edad As Integer

End Class

Sub Main()

Dim Manuel As New Persona()

Manuel.Apellido = "Salas"

Manuel.Nombre = "Manuel"

Manuel.Edad = 30

Dim archivo As New FileStream("c:\temp\f_persona.dat", FileMode.Create)

Dim formateador As New Binary.BinaryFormatter

formateador.Serialize(archivo, Manuel)

archivo.Close()

End Sub

End Module

Como podemos observar básicamente son tres pasos los que debemos realizar para serializar un objeto:

  1. Instanciamos un FileStream para almacenar el objeto serializado.
  2. Instanciamos un Formateador para serializar el objeto.
  3. Serializamos el objeto llamando al método serialize del formateador.

Para des-serializar un objeto seguimos los mismos pasos de manera inversa:

  1. Instanciamos un FileStream para leer el objeto serializado.
  2. Instanciamos un Formateador para des-serializar el objeto.
  3. Des-serializamos el objeto llamando al método deserialize del formateador.

Veamos como des-serializar el objeto que serializamos en el fragmento de código anterior:

Imports System.IO

Imports System.Runtime.Serialization

Imports System.Runtime.Serialization.Formatters

Module Module1

<System.Serializable()> Public Class Persona

Public Nombre As String

Public Apellido As String

Public Edad As Integer

End Class

Sub Main()

Dim Manuel As New Persona()

Dim archivo As New FileStream("c:\temp\f_persona.dat", FileMode.Open)

Dim formateador As New Binary.BinaryFormatter

Manuel = formateador.Deserialize(archivo)

archivo.Close()

Console.WriteLine("Nombre ={0}, Apellido = {1}, Edad = {2}", Manuel.Nombre, Manuel.Apellido, Manuel.Edad)

Console.ReadKey()

End Sub

End Module

Como podemos observar en el ejemplo anterior, cuando creamos una clase personalizada y queremos serializarla debemos marcarla con el atributo <System.Serializable()>. También podemos seleccionar las propiedades que no queremos serializar, para esto utilizamos el atributo <System.NonSerialized()> antes del nombre de la propiedad que deseamos no serializar.

08 junio, 2007

Serialización

Serialización es el proceso mediante el cual tomamos un objeto y almacenamos su estado, de forma que lo podamos transportar o recuperar posteriormente. Esta tarea nos la facilita el framework mediante el namespace System.Runtime.Serialization.

Hay cuatro formatos diferentes para serializar un objeto:

Binaria:

Este formato es recomendado cuando el objeto serializado va a ser des-serializados solo en aplicaciones dot.net.

SOAP:

Este formato es basado en XML y es recomendado cuando el objeto será des-serializado en diferentes plataformas o cuando va a ser trasportado por la red. Los objetos serializados con este formato pueden ser tres o cuatro veces más grandes que los serializados mediante el formato binario.

XML:

Este formato es basado en XML y es recomendado cuando el objeto será des-serializado en diferentes plataformas o cuando va a ser trasportado por la red siempre y cuando no se requiera serializar miembros privados. Este formato brinda una gran interoperabilidad y es muy fácil de comprender.

Custom:

Aunque los anteriores formatos permiten una gran personalización, en algunos casos es necesario hacer una serialización totalmente personalizada, implementando la interface Iserializable.

02 junio, 2007

Colecciones basadas en llaves y valores (Diccionarios)

Siguiendo con el tema de las colecciones vamos a ver otro tipo de colecciones, las que almacenan pares de valores (una llave y un valor).

Hashtable

El Hashtable es una colección que guarda pares de valores, almacena una llave y un valor. Usualmente es usada cuendo se requiere obtener un valor basado alguna clave que conocemos. Por ejemplo, un nombre de usuario asociado a un nombre completo, o un código asociado a un proveedor, veamos el ejemplo:

Imports System.Collections

Module Module1

Sub Main()

Dim clientes As New Hashtable

clientes.Add("01", "Cliente_01")

clientes.Add("02", "Cliente_02")

clientes.Add("03", "Cliente_03")

clientes.Add("04", "Cliente_04")

For Each cliente As DictionaryEntry In clientes

Console.WriteLine("Código: {0}, Nombre: {1}", cliente.Key, cliente.Value)

Next

Console.ReadKey()

End Sub

End Module

Es importante que tomemos en cuenta que si tratamos de almacenar dos entradas con la misma llave, la primer entrada será sustituida, podemos decir más técnicamente que si el hash de las dos llaves es igual el valor será sustituido.

SortedList

Es prácticamente igual al hashtable con la diferencia que en esta colección los datos se almacenan de manera ordenada. Veamos:

Imports System.Collections

Module Module1

Sub Main()

Dim clientes As New SortedList

clientes.Add("03", "Cliente_03")

clientes.Add("02", "Cliente_02")

clientes.Add("04", "Cliente_04")

clientes.Add("01", "Cliente_01")

For Each cliente As DictionaryEntry In clientes

Console.WriteLine("Código: {0}, Nombre: {1}", cliente.Key, cliente.Value)

Next

Console.ReadKey()

End Sub

End Module

ListDiccionary

Es ListDiccionary es prácticamente igual al hashtable, solo que es más eficiente para colecciones pequeñas. Es considerada como una colección especializada, por eso la encontramos en System.Collections.Specialized. Veamos:

Imports System.Collections

Imports System.Collections.Specialized

Module Module1

Sub Main()

Dim clientes As New ListDictionary

clientes.Add("03", "Cliente_03")

clientes.Add("02", "Cliente_02")

clientes.Add("04", "Cliente_04")

clientes.Add("01", "Cliente_01")

For Each cliente As DictionaryEntry In clientes

Console.WriteLine("Código: {0}, Nombre: {1}", cliente.Key, cliente.Value)

Next

Console.ReadKey()

End Sub

End Module

HybridDictionary

Esta es otra colección especializada, vimos anteriormente que tenemos el hashtable, muy eficiente para colecciones grandes, y luego el ListDictionary para colecciones pequeñas, pero que pasa cuando la colección que estamos implementando es algunas veces grande y otras veces pequeña, para estos casos se recomiendo la implementación mediante el HybridDictionary, ya que esta colección tiene la capacidad de comportarse como un ListDictionary pero cuando la colección crece automáticamente se trasforma en un Hashtable, siendo entonces bastante eficiente para ambientes irregulares (donde el tamaño de las colección varía sustancialmente).

Imports System.Collections

Imports System.Collections.Specialized

Module Module1

Sub Main()

Dim clientes As New HybridDictionary

clientes.Add("03", "Cliente_03")

clientes.Add("02", "Cliente_02")

clientes.Add("04", "Cliente_04")

clientes.Add("01", "Cliente_01")

For Each cliente As DictionaryEntry In clientes

Console.WriteLine("Código: {0}, Nombre: {1}", cliente.Key, cliente.Value)

Next

Console.ReadKey()

End Sub

End Module

OrderedDictionary

El OrderedDictionary es otra colección especializada, y nos da prácticamente la misma funcionalidad de un hashtable, pero agrega la funcionalidad necesaria para poder acceder los ítems por medio de un índice. Adicional a los métodos del hashtable el OrderedDictionary tiene un insert y un removeat para poder controlar el orden de los elementos. Pero mejor veamos un ejemplo:

Imports System.Collections

Imports System.Collections.Specialized

Module Module1

Sub Main()

Dim clientes As New OrderedDictionary

clientes.Add("03", "Cliente_03")

clientes.Insert(0, "02", "Cliente_02")

clientes.Add("04", "Cliente_04")

clientes.Insert(0, "01", "Cliente_01")

For Each cliente As DictionaryEntry In clientes

Console.WriteLine("Código: {0}, Nombre: {1}", cliente.Key, cliente.Value)

Next

Console.ReadKey()

End Sub

End Module