ÍndiceGestionando el sistema de archivosLeyendo y escribiendo datos mediante StreamsCompresión y protección de datos mediante StreamsAmpliando la seguridad de las aplicaciones utilizando almacenamiento aislado.Serialización y Deserialización de objetos mediante Runtime SerializationPersonalización de los procesos de Runtime Serialization y DeserializationSerialización y Deserialización de objetos como datos XML
Todas las aplicaciones, excepto las más triviales, requieren algún tipo de entrada o salida de datos y, en muchos casos, se efectúa contra archivos..NET Framework nos provee de un conjunto de clases que nos permiten acceder al sistema de archivos del sistema, navegar por las carpetas, crear y eliminas archivos y leer y escribir en los mismos, implementado mediante un modelo de streaming. Adicionalmente podemos encriptar y comprimir los datos al almacenarlos en un archivo o en memoria.Aunque dado que la gestión de datos en memoria tiene sus limitaciones .NET nos suministra el almacenamiento aislado, para ayudarnos a persistir los datos privados a disco, peor protegidos de programas maliciosos. Esta técnica nos permite asignar un espacio de archivos para un usuario, aplicación o ensamblado, el cual será independiente de cualquier otro usuario, aplicación o ensamblado.
Gestión de archivos y Serialización
Gestionando el sistema de archivos
Las clases File y FileInfo del espacio de nombres System.IO
Leer mediante la clase File
Las clases Directory y DirectoryInfo
La clase DriveInfo
Información de ruta de archivos y carpetas
Monitorizar cambios en archivos o carpetas
Gestión de archivos y Serialización
Gestión de archivos y Serialización
using System.IO;...File.Copy(@"E:\Democode\MyFile.txt", @"E:\Democode\CopyFile.txt", true);File.SetAttributes(@"E:\Democode\CopyFile.txt",
FileAttributes.ReadOnly | FileAttributes.Hidden);
using System.IO;…FileInfo dataFileInfo = new FileInfo(@"E:\Democode\MyFile.txt");dataFileInfo.CopyTo(@"E:\Democode\CopyFile.txt", true);FileInfo copyFileInfo = new FileInfo(@"E:\Democode\CopyFile.txt");copyFileInfo.Attributes = FileAttributes.ReadOnly | FileAttributes.Hidden;
Las clases File y FileInfoClase FileProvee métodos estáticos static (Shared) Recibe el nombre de archivo como un parámetroTiene métodos para modificar atributosComprueba la autorización del usuario en cada llamada a métodoSe puede utilizar para ejecutar una operación aislada con un archivo.
FileInfo classProvee métodos de instancia.Recibe el nombre de archivo como parámetros en el constructor.Tiene propiedades para modificar atributos.Comprueba la autorización en cada llamadaSe puede utilizar para realizar mútiples operaciones con un archivo
Create
Copy/CopyTo
Delete
Move/MoveTo
Exists
Replace
Encrypt
Decrypt
Leer y escribir con la clase File
Gestión de archivos y Serialización
WriteAllBytes
ReadAllBytes
ReadAllLines
ReadAllText
WriteAllLines
WriteAllText
AppendAllText
Las clases Directory y DirectoryInfo
Gestión de archivos y Serialización
La clase DirectoryProvee métodos estáticos static (Shared)
Recibe el nombre de carpeta como parámetro
Incluye métodos que no están disponibles con la clase DirectoryInfo
Puede usarse para ejecutar una operación aislada con una carpeta
La clase DirectoryInfoProvee métodos de instancia
Recibe el nombre de carpeta en el constructor
Incluye el método CreateSubdirectory que no está en la clase Directory
Se usa para ejecutar múltiples operaciones con una carpeta
CreateDirectory/Create GetDirectories
Delete Move/MoveTo
Exists GetFiles
GetFileSystemEntries/GetFileSystemInfos
Gestión de archivos y Serialización
Las clases Directory y DirectoryInfoDirectory classImports System.IO...Dim currentFolder As StringcurrentFolder = Directory.GetCurrentDirectory()Dim fileAndFolderNames() As StringfileAndFolderNames = Directory.GetFileSystemEntries(currentFolder)For Each entry As String In fileAndFolderNames
Console.WriteLine("{0}", entry)Next entry
DirectoryInfo classDim backupFolder As New DirectoryInfo("E:\Democode\backup")If Not backupFolder.Exists Then
backupFolder.Create()End IfDim currentFolderName As StringcurrentFolderName = Directory.GetCurrentDirectory()Dim currentFolder As New DirectoryInfo(currentFolderName)For Each entry As FileInfo In currentFolder.GetFiles()
entry.CopyTo(backupFolder.FullName + "\" + entry.Name)Next entry
La clase DriveInfo
Gestión de archivos y Serialización
Provee métodos y propiedades para recuperar información de dispositivos
Soporta discos fijos y portátiles, CD/DVD, diskettes y discos de red
GetDrives
DriveType
TotalFreeSpace
IsReady
RootDirectory
AvailableFreeSpace
DriveFormat
TotalSize
VolumeLabel
Obtener información de la ruta de archivos y carpetas
Gestión de archivos y Serialización
La clase PathProvee campos y métodos estáticos static (Shared) que permiten trocear nombres de archivo y carpetasSiendo consciente de las capacidades y limitaciones del sistema de archivosTiene métodos para la generación de nombres de archivo únicos y temporales: GetTempFileName , GetRandomFileName
E:\Democode\TestFolder\TestFile.txt
GetDirectoryName
GetExtension
GetFileName
DirectorySeparatorVolumeSeparator
GetPathRoot
E:\Democode\TestFolder\TestFile.txtE:\Democode\TestFolder\TestFile.txtE:\Democode\TestFolder\TestFile.txtE:\Democode\TestFolder\TestFile.txtE:\Democode\TestFolder\TestFile.txtE:\Democode\TestFolder\TestFile.txt
Monitorizar cambios en archivos o carpetas
Gestión de archivos y Serialización
La clase FileSystemWatcherMonitoriza una carpeta y genera un evento si cambia un archivo o sub-carpeta
Crear un objeto FileSystemWatcher
Fijar la propiedad Path en la carpeta a monitorizar
Fijar las propiedades Filter y NotifyFilter para indicar los cambios a monitorizar
Informar la propiedad IncludeSubDirectory
Manejar los eventos Created, Changed, Deleted y Renamed
Fijar la propiedad EnableRaisingEvents a True
11
33
44
22
Filter: *.txt
NotifyFilter: Filename
Changed
DeletedCreated
Renamed
55
66
Leer y escribir datos mediante Streams¿Qué es un Stream de entrada / salida?La clase FileStreamLeer y escribir texto en un StreamLeer y escribir texto binario en un StreamLeer y escribir datos temporales en memoria¿Cómo añadir buffering a un Stream Unbuffered
La clase File nos suministra métodos static o Shared para efectuar lecturas y escrituras básicas en archivos.
Sin embargo las aplicaciones deben efectuar, normalmente, accesos a los datos más selectivos.
.NET Framework implementa un modelo de Streaming que podemos utilizar para acceder a los datos contenidos en los archivos.
Algunos de estos Streams permiten accede aleatorio, lo cual habilita la búsqueda de valores concretos para localizar la posición inicial y leer a partir de ahí o la inserción d datos en posiciones distintas del final de archivo.
Gestión de archivos y Serialización
¿Qué es un Stream de entrada/salida?
Gestión de archivos y Serialización
Un flujo de datos desde un origen a un destino mediante un único canal.Los daos se reciben en el orden en el que se envían.
La clase Stream (utilizada mediante FileStream o MemoryStream)Es la clase base par todos los Streams de .NET.Implementa métodos y propiedades que manejan un Stream como una serie de bytes (ReDim with SetLength).Provee soporte para acceso aleatorio.Utiliza el soporte de hardware, cuando está disponible, para grandes cantidades de datos.Utiliza un puntero interno a la ubicación de los datos en origen.
Read
ReadByte
Write
Flush
CanSeek
CanWrite
CanRead
Seek
WriteByte
Close
Length
Position
La clase FileStream
Gestión de archivos y Serialización
Es una implementación de la clase Stream para la lectura y escritura de archivos.
Se especifica la ruta, el archivo, el modo de apertura, el tipo de acceso, el tamaño de buffer y el acceso compartido en el constructor.
Read bytes
Write bytes
FileStream
Gestión de archivos y Serialización
La clase FileStreamusing System.IO;byte[] firstMessage = new byte[] { Convert.ToByte('H'), Convert.ToByte('o'), Convert.ToByte('l'), Convert.ToByte('l'), Convert.ToByte('a') };byte[] secondMessage = new byte[] { Convert.ToByte(' '), Convert.ToByte('M'), Convert.ToByte('u'), Convert.ToByte('n'), Convert.ToByte('d'), Convert.ToByte('o') };
using (FileStream file = new FileStream(@"E:\Democode\Greetings.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{file.Lock(0, firstMessage.Length + secondMessage.Length);file.Write(firstMessage, 0, firstMessage.Length);file.Write(secondMessage, 0, secondMessage.Length);file.Unlock(0, firstMessage.Length + secondMessage.Length);file.Seek(-3, SeekOrigin.End);byte[] dataRead = new byte[3];file.Read(dataRead, 0, dataRead.Length);Console.WriteLine("Final 3 bytes: {0}{1}{2}",Convert.ToChar(dataRead[0]), Convert.ToChar(dataRead[1]), Convert.ToChar(dataRead[2]));file.Close();
}
Final 3 bytes: rld
Leer y escribir texto en un Stream
Gestión de archivos y Serialización
Las clases StreamReader y StreamWriter Convierten entre datos de texto y Stream de bytes
Dispone de métodos orientados a texto
Se utiliza con un objeto FileStream para leer y escribir datos como texto
FileStream
Read text
Write text
StreamReader
StreamWriter
Read
ReadLine
Peek
Write
WriteLine
Flush
La clase FileStream proporciona un medio muy rápido para leer y escribir datos como series de bytes.Será necesario efectuar las conversiones entre los datos en bruto y los tipos adecuados (serialización y deserialización).Las clase de .NET que pueden serializar los datos y deserializar series de bytes desde un stream hacia tipos primitivos o string de forma automática son, por ejemplo, StreamReader y StreamWriter.
Gestión de archivos y Serialización
Leer y escribir texto en un Stream
using System.IO;...string customerName = "John";int customerAge = 43;string customerNationality = "British";string data = "";using (StreamWriter writer = new StreamWriter(@"E:\Democode\Customers.txt")){writer.WriteLine("Customer Name: {0}", customerName);writer.WriteLine("Age: {0}", customerAge);writer.WriteLine("Nationality: {0}", customerNationality);writer.Close();
}using (StreamReader reader = new StreamReader(@"E:\Democode\Customers.txt")){data = reader.ReadLine();Console.WriteLine("{0}", data);data = reader.ReadLine();Console.WriteLine("{0}", data);data = reader.ReadLine();Console.WriteLine("{0}", data);reader.Close();
}
Customer Name: JohnAge: 43Nationality: British
Leer y escribir datos binarios en un Stream
Gestión de archivos y Serialización
Las clases BinaryReader y BinaryWriter
Convierten entre tipos de .NET Framework y Stream de bytes
Dispone de métodos para leer y escribir tipos primitivos
FileStream
Read binary data
Write binary data
BinaryReader
BinaryWriter
Read/WriteChar
Read/WriteInt32
Read/WriteString
Read/WriteDouble
…
Leer y escribir datos temporales en memoria
Gestión de archivos y Serialización
MemoryStream
La clase MemoryStreamEs una implementación de la clase Stream que accede a la memoria.
Incluye métodos que copian datos a un Array u otro Stream.
Puede utilizarse con objetos Binary/StreamReader y Binary/StreamWriter para leer y escribir datos de texto o binarios.
Similar a FileStream pero almacenando en memoria.
Read binary/text
data
Binary/StreamReader
Binary/StreamWriter
Write binary/text
data
ToArray
WriteTo
Como añadir Buffering a un Stream Unbuffered
Gestión de archivos y Serialización
La clase BufferedStreamAñade almacenamiento temporal a un Stream que no disponga de él (Stream, NetworkStream o streams personalizados).
Actúa como un wrapper arropando un Stream unbuffered
Implementa métodos de Stream, pero los datos se almacenan temporalmente hasta que se lancen los métodos Flush o Close o el buffer esté lleno.
Se debe especificar el tamaño del buffer en el constructor.
Flush
BufferedStream
Unbuffered Stream
Compresión y protección de datos mediante StreamsLa clase DeflateStream para compresión de datos.La clase GZipStream para compresión de datos.La clase CryptoStream para encriptado de datos.
El modelo de streaming permite también que las aplicaciones transformen los datos que están siendo leídos o escritos de un archivo y .NET dispone de clases que pueden comprimir y encriptar los datos a medida que se procesan.
Estas características son muy útiles si se quiere reducir el espacio ocupado por un archivo o protege rel contenido del mismo de miradas indiscretas.
Gestión de archivos y Serialización
La clase DeflateStream para compresión de datos
Comprime y descomprime los datos de un Stream de bytes
Implementa el algoritmo Deflate
No soporta acceso aleatorio produciendo una excepción NotSupportedException
Reside en el espacio de nombre System.IO.Compression
El tamaño máximo de Stream es de 4 Gb.
Gestión de archivos y Serialización
DeflateStream
Gestión de archivos y Serialización
La clase DeflateStream para compresión de datosusing System.IO;using System.IO.Compression;// Datos a comprimirstring[] data = new string[] { "En un lugar de ola mancha", "de cuyo nombre no me quiero acordar", "vivia, no ha mucho un caballero.."};// Compone un stream para escribir y comprimirusing (FileStream file = new FileStream(@"E:\Democode\CompressedData.dat",FileMode.Create, FileAccess.Write)) {using (DeflateStream deflate = new
DeflateStream(file,CompressionMode.Compress)) {StreamWriter writer = new StreamWriter(deflate);// Escribe los datos en el stream comprimidoforeach (string item in data) {
writer.WriteLine(item);}writer.Close();
}}
La clase GZipStream para compresión de datos
Gestión de archivos y Serialización
GZipStream
Comprime y descomprime datos en un Stream de bytes
Implementa el algoritmo Deflate
Formatea los datos según la especificación GZIP (Gzip, WinZip, WinRar)
La clase CryptoStream para encriptado de datos
Gestión de archivos y Serialización
Encripta y desencripta datos en un Stream de bytes
Aplica una transformación criptográfica especificada por un objeto ICryptoTransform
.NET incluye varios proveedores de servicios criptográficos y el espacio de nombres System.Security.Cryptography
CryptoStream
ICryptoTransform Object
Gestión de archivos y Serialización
using System.IO; using System.Security.Cryptography; string[] data = new string[] { "Top", "Secret", "Data" }; FileStream fileWriter = new FileStream(@"E:\Democode\SecretData.bin", FileMode.Create, FileAccess.Write); // Especifica la encriptación DES y genera la clave y el vectorDESCryptoServiceProvider dcspWriter = new DESCryptoServiceProvider(); dcspWriter.GenerateKey(); dcspWriter.GenerateIV(); byte[] key = dcspWriter.Key; // Salva la clavebyte[] vector = dcspWriter.IV; // Salva el vector// Crea un CryptoStream y encripta los datosICryptoTransform transformWriter = dcspWriter.CreateEncryptor(); CryptoStream cryptoWriter = new CryptoStream(fileWriter, transformWriter, CryptoStreamMode.Write); StreamWriter writer = new StreamWriter(cryptoWriter); foreach (string item in data) { writer.WriteLine(item); } writer.Close();
using System.IO; using System.Security.Cryptography; // Lee y desencripta los datosFileStream fileReader = new FileStream(@"E:\Democode\SecretData.bin", FileMode.Open, FileAccess.Read); DESCryptoServiceProvider dcspReader = new DESCryptoServiceProvider(); ICryptoTransform transformReader = dcspReader.CreateDecryptor(key, vector); CryptoStream cryptoReader = new CryptoStream(fileReader, transformReader, CryptoStreamMode.Read); StreamReader reader = new StreamReader(cryptoReader); string line = reader.ReadLine(); while (line != null) { Console.WriteLine("{0}", line); line = reader.ReadLine(); } reader.Close();
Ampliando la seguridad de las aplicaciones utilizando almacenamiento aislado
¿Qué es el almacenamiento aislado?¿Cómo gestionar archivos y carpetas en almacenamiento aislado?¿Cómo leer y escribir archivos en almacenamiento aislado?
Muy a menudo las aplicaciones deben crear archivos temporales o de configuración de usuario, los cuales pueden contener información sensible.
Para pequeñas cantidades de datos que tengan un periodo de vida muy corto, podemos mantener esta información en memoria.
Pero no siempre es éste el mejor enfoque para ello.
Adicionalmente, podemos querer retener esta información entre ejecuciones de la aplicación.
Sin embargo, hay varios consideraciones a tener en cuenta: La aplicación puede no tener suficientes privilegios para crear archivos en disco. Si la información es confidencial, está claro que no querremos que se almacene en
una ubicación genérica, a la disposición de todo el que acceda al ordenador. De la misma forma, si hay varios ensamblados corriendo en le máquina, es posible
que no deseemos que el resto de ensamblados puedan acceder a dicha información. Sobre todo para aquellos procesos descargados de la red.
.NET Framework dispone del Isolated Storage para ayudarnos a solucionar estos problemas.
Gestión de archivos y Serialización
¿Qué es el almacenamiento aislado?
Gestión de archivos y Serialización
Es un almacenamiento de archivos privativo de un ensamblado y completamente aislado del reservado para otros ensamblados.
Isolated storage
Los ensamblados sólo requieren el permiso IsolatedStorageFilePermission para crear y acceder al almacenamiento aislado.
Privilegios
Ámbito del almacenamiento aislado
Isolated storage está compuesto de almacenes gestionados en compartimientos de datos• Cada usuario tiene su propio compartimiento en Local Settings \
Application Data \ Isolated Storage• También hay compartimientos a nivel de máquina• Cada ensamblado tiene su propio almacén en un compartimiento de
datosDiferentes ensamblados no pueden acceder fácilmente al almacén de otro.• También se pueden aislar diferentes instancias del mismo ensamblado
que se ejecuten en diferentes dominios de aplicación.Las aplicaciones ClickOnce pueden crear almacenes a nivel de aplicación
¿Cómo gestionar archivos y carpetas en almacenamiento aislado?
Gestión de archivos y Serialización
La clase IsolatedStorageFileImplementa un sistema de archivos en almacenamiento aislado
Dispone de métodos para crear y acceder un almacén de Isolated Storage con un ámbito específico.
Contiene métodos para crear y gestionar archivos y carpetas en un almacén Isolated Storage
GetStore
GetUserStoreForAssembly
GetUserStoreForDomain
GetUserStoreForApplication
GetMachineStoreForAssembly
GetMachineStoreForDomain
GetMachineStoreForApplication
CreateDirectory
DeleteDirectory
GetDirectoryNames
DeleteFile
GetFileNames
Remove
Close
Gestión de archivos y Serialización
¿Cómo gestionar archivos y carpetas en almacenamiento aislado?using System; using System.IO; using System.IO.IsolatedStorage; // Crea una serie de carpetasIsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForDomain(); isolatedStorage.CreateDirectory("PrivateFolder1"); isolatedStorage.CreateDirectory("PrivateFolder2"); isolatedStorage.CreateDirectory("PrivateFolder3"); isolatedStorage.CreateDirectory("TestFolder"); isolatedStorage.Close(); // Lista las carpetas IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForDomain(); string[] foldernames = isolatedStorage.GetDirectoryNames("Private*"); foreach (string name in foldernames) { Console.WriteLine("{0}", name); } isolatedStorage.Close();
// la salida debería parecerse a estoPrivateFolder1 PrivateFolder2 PrivateFolder3
¿Cómo leer y escribir archivos en almacenamiento aislado?
Gestión de archivos y Serialización
La clase IsolatedStorageFileStreamEs una clase FileStream para crear, leer y escribir archivos en Isolated StorageSe utiliza con objetos Binary / StreamReader y Binary / StreamWriter para leer y escribir datos de texto y binariosSe utiliza con objetos DeflateStream o GZipStream y CryptoStream para comprimir y encriptar datos
Read binary/text
data
Binary/StreamReader
Binary/StreamWriter
Write binary/text
data
IsolatedStorageFileStream
Gestión de archivos y Serialización
¿Cómo leer y escribir archivos en almacenamiento aislado?using System;using System.IO;using System.IO.IsolatedStorage;// Crea un archivo en almacenamiento aisladostring[] data = new string[] { "Private", "User", "Data" };IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForDomain();isolatedStorage.CreateDirectory("Demodata");IsolatedStorageFileStream fileStream = newIsolatedStorageFileStream(@"Demodata\Private.txt", FileMode.Create,FileAccess.Write, isolatedStorage);StreamWriter writer = new StreamWriter(fileStream);foreach (string item in data) {
writer.WriteLine(item);}writer.Close();isolatedStorage.Close();// Lee el archivoIsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForDomain();IsolatedStorageFileStream fileStream = newIsolatedStorageFileStream(@"Demodata\Private.txt", FileMode.Open,FileAccess.Read, isolatedStorage);StreamReader reader = new StreamReader(fileStream);string line = reader.ReadLine();while (line != null) {
Console.WriteLine("{0}", line);line = reader.ReadLine();
}reader.Close();isolatedStorage.Close();
The output of this code resembles the following example when it is run on the LON-DEV-05 virtual machine.
Private User Data
Serialización y DeserializaciónSerialización y deserialización de objetos mediante serialización en tiempo de ejecuciónPersonalización de los procesos de serialización y deserializaciónSerialización y deserialización de objetos como datos XML
Las clases StreamReader, StreamWriter, BinaryReader y BinaryWriter de la BCL nos permiten construir aplicaciones que pueden leer y escribir texto y tipos primitivos de datos utilizando Streams.Sin embargo, en muchos casos es necesario leer y escribir estructuras de datos definidas por nuestras propias clases y estructuras.Además, es posible que deseemos emitir estos datos en un formato diferente al de la codificación estándar que implementen dichas clases, por ejemplo en XML.El proceso de convertir objetos en un formato que pueda ser escrito en un Stream se llama serialización.Y el proceso inverso de conversión desde un Stream a objetos se llama deserialización.
Gestión de archivos y Serialización
Serialización y Deserialización de objetos utilizando Runtime Serialization
El proceso de serializaciónCómo definir un tipo serializable.El proceso de deserializaciónComo serializa y deserializa los tipos complejos y las colecciones .NET
Cuando serializamos un objeto, éste es convertido en una serie de bytes, que después se envían a un Stream.El cuál puede apuntar a un almacenamiento persistente, a una dirección de red o hacia algún otro destino.
Gestión de archivos y Serialización
El proceso de serialización
Gestión de archivos y Serialización
El proceso de convertir un objeto en una serie de bytesSerialización
Serialización en tiempo de ejecuciónLas clases BinaryFormatter (.NET) y SoapFormatter controlan el formato e serialización (Espacios de nombres System.Runtime.Serialization.Formatters.Binary y System.Runtime.Serialization.Formatters.Soap)
Ambos implementan el interfaz IFormatter
Los objetos a serializar: Deben ser instancias de clases serializables Pueden implementar el interfaz ISerializable
Binary
SOAP
Serialize
Deserialize
Serialize
DeserializeObjetoserializable
GetObjectData
Gestión de archivos y Serialización
El proceso de serializaciónusing System.Runtime.Serialization.Formatters.Soap;using System.IO;string message = "The cost of product 99 is:";decimal price = 149.99M;using (FileStream fileStream = new FileStream(@"E:\Democode\SoapData.txt",FileMode.OpenOrCreate, FileAccess.Write)){
SoapFormatter soapFormatter = new SoapFormatter();soapFormatter.Serialize(fileStream, message);soapFormatter.Serialize(fileStream, price);soapFormatter.Serialize(fileStream, String.Format("{0} {1}", message, price));fileStream.Close();
}
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAPENC=“http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAPENV=“http://schemas.xmlsoap.org/soap/envelope/” xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAPENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><SOAP-ENC:string id="ref-1">The cost of product 99 is:</SOAP-ENC:string>
</SOAP-ENV:Body></SOAP-ENV:Envelope><SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAPENC=“http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAPENV=http://schemas.xmlsoap.org/soap/envelope/xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAPENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><xsd:decimal id="ref-1">
<flags>131072</flags><hi>0</hi><lo>14999</lo><mid>0</mid>
</xsd:decimal></SOAP-ENV:Body>
</SOAP-ENV:Envelope><SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance”xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAPENC=“http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAPENV=“http://schemas.xmlsoap.org/soap/envelope/"xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAPENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><SOAP-ENC:string id="ref-1">The cost of product 99 is: 149.99</SOAP-ENC:string>
</SOAP-ENV:Body></SOAP-ENV:Envelope>
¿Cómo definir un tipo serializable?
Gestión de archivos y Serialización
Aquél marcado con el atributo System.SerializableAttribute
Tipo serializable
Tipos serializablesTodos los campos de instancia se serializan (no static/shared):
Public and private
Para omitir un campo hay que marcarlo con el atributo NonSerializedAttribute
Los tipos de clases base también han de ser serializables
Serializable
FirstNameLastNamepasswordcreditCardPinbankAccountNumber
NonSerializedNonSerialized
BankCustomer
PersonSerializable
Gestión de archivos y Serialización
¿Cómo definir un tipo serializable?using System.Runtime.Serialization.Formatters.Soap;using System.IO;using System;...[Serializable]class Data{
private string privateData = "This is private data";public string publicData = "This is public data";[NonSerialized]private string otherPrivateData = " This data will not be serialized"
}...Data data = new Data();using (FileStream fileStream = new FileStream(@"E:\Democode\SoapData.txt",FileMode.OpenOrCreate, FileAccess.Write)){
SoapFormatter soapFormatter = new SoapFormatter();soapFormatter.Serialize(fileStream, data);fileStream.Close();
}
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAPENC=“http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAPENV=“http://schemas.xmlsoap.org/soap/envelope/”xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAPENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <a1:Data id="ref-1”xmlns:a1="http://schemas.microsoft.com/clr/nsassem/SerializationVB/ SerializationVB%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull"> <privateData id="ref-3">This is private data</privateData> <publicData id="ref-4">This is public data</publicData> </a1:Data> </SOAP-ENV:Body></SOAP-ENV:Envelope>
El proceso de deserialización
Gestión de archivos y Serialización
El proceso de construir un objeto a partir de una serie de bytes
Deserialización
Deserializando datosLlamar al método Deserialize del objeto formatter
Asegurarse de que la información del tipo en el stream de serialización es compatible con la versión del objeto en deserialización
Utilizar el atributo OptionalFieldAttribute o un binder para solventar los problemas de versiones
Formatter
Deserialize
AccountNumberDateOpenedBalance
OptionalField
AccountData
Binder
Como serializa y deserializa .NET los tipos complejos y las colecciones
Gestión de archivos y Serialización
Name [string]
Father [Person]
Mother [Person]
Person
Ref: 1 Name: JohnRef: 2Name: DianaRef: 3Name: FrancescaFather: 1Mother: 2
Formatter
Serialize
Name: John
Name: Diana
Name: Francesca
Father: John
Mother: Diana
Serializando y deserializando dependenciasFormatter genera Ids de referencia
El Stream de serialización referencia los objetos mediante esos Ids
Formatter utiliza ObjectManager para resolver las dependencias de objetos en la deserialización
Y ejecuta inicializaciones adicionales implementando el interfaz IDeserializationCallback
Deserialize
ObjectManager
11
33
22
Gestión de archivos y SerializaciónComo serializa y deserializa .NET los tipos complejos y las colecciones<Serializable()> Class Person
Public Name As StringPublic Father As PersonPublic Mother As Person
End Class
Dim mum As New Person()mum.Name = "Diana"Dim dad As New Person()dad.Name = "John"Dim daughter As New Person()daughter.Name = "Francesca"daughter.Mother = mumdaughter.Father = dadUsing serializationStream As New FileStream("E:\Democode\daughter.txt", FileMode.Create, FileAccess.Write)
Dim soapWriter As New SoapFormatter()soapWriter.Serialize(serializationStream, daughter)serializationStream.Close()
End Using
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance”xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAPENC=“http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAPENV=“http://schemas.xmlsoap.org/soap/envelope/”xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAPENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><a1:Person id="ref-1”xmlns:a1="http://schemas.microsoft.com/clr/nsassem/Serialization/Serialization%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<Name id="ref-3">Francesca</Name><Father href="#ref-4"/><Mother href="#ref-5"/>
</a1:Person><a1:Person id="ref-4”xmlns:a1="http://schemas.microsoft.com/clr/nsassem/Serialization/Serialization%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<Name id="ref-6">John</Name><Father xsi:null="1"/><Mother xsi:null="1"/>
</a1:Person><a1:Person id="ref-5”xmlns:a1="http://schemas.microsoft.com/clr/nsassem/Serialization/Serialization%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<Name id="ref-7">Diana</Name><Father xsi:null="1"/><Mother xsi:null="1"/>
</a1:Person></SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Personalización de la serialización en tiempo de ejecución
Personalizando el proceso de serialización
Personalizando el proceso de deserialización
Implementación de la clase Custom Formatter
Gestión de archivos y Serialización
Personalizando el proceso de serialización
Gestión de archivos y Serialización
Interfaz ISerializable Implementa el método GetObjectData
Alimenta el parámetro SerializationInfo al ser llamado con el método Serialize
Eventos de serializaciónUtiliza el atributo OnSerializingAttribute para marcar un método que se ejecuta antes de que comience la serialización
Utiliza el atributo OnSerializedAttribute para marcar un método que se ejecuta cuando la serialización se ha completado
GetObjectDataSerializingSerialized
CustomClass
Formatter
Serialize
SerializationInfoOnSerializingOnSerialized
Personalizando el proceso de deserialización
Gestión de archivos y Serialización
Requerimientos de una clase personalizadaRequiere un constructor de deserialización
Alimentar el objeto con los datos del parámetro SerializationInfo
Eventos de deserializaciónUtilizar el atributo OnDeserializingAttribute para marcar un método para que se ejecute antes de que comience la deserializaciónY OnDeserializedAttribute para otro método cuando se haya completado
Deserialization Constructor
Deserializing
Deserialized
CustomClass
Formatter
DeserializeSerializationInfo
OnDeserializing
OnDeserialized
Implementación de la clase Custom Formatter
Gestión de archivos y Serialización
Implementar IFormatter.Serialize
Si el objeto implementa ISerializable, llamar GetObjectDataUtilizar la clase de apoyo FormatterServices para recuperar los miembros a serializarEscribir los metadatos del objetos y sus datos al Stream de serializaciónUtilizar la clase de apoyo SerializationObjectManager para lanzar los eventos de serialización
Implementar IFormatter.Deserialize
Leer el Stream de serialización y extraer los metadatos y datosUtilizar la clase de apoyo FormatterServices para crear una instancia vacía del objetoSi el objeto dispone de un constructor de deserialización, llamarlo para alimentar al objeto, en caso contrario, cumplimentar la información en el método DeserializeUtilizar un objeto ObjectManager para gestionar las referencias y lanzar los eventos
Serialización y deserialización de objetos como datos XML
Cómo serializar un objeto como XML
Como la clase XmlSerializer serializa datos complejos
Como especificar definición de tipos XML y espacios de nombres
Como controlar la serialización XML para un tipo
Personalización del proceso de serialización XML
Como deserializar un objeto desde un Stream XML
Gestión de archivos y Serialización
Cómo serializar un objeto como XML
Gestión de archivos y Serialización
Uso de la clase XmlSerializer Crear un objeto XmlSerializer y especificar el tipo de objeto a serializar
Llamar al método Serialize y enviar los datos a un objeto Stream, TextWriter o XmlWriter
Requerimientos de un tipo serializableDebe ser un tipo público
No necesita el atributo Serializable
Debe disponer de un constructor por defecto público (para deserializar)
Debe tener acceso público a los campos y propiedades que contiene los datos a serializar
BankCustomer()
Public BankCustomer
CustomerName
creditCardPin
Serializable<?xml version="1.0"><BankCustomer xmlns:xsi="... " > <CustomerName>Fred</CustomerName></BankCustomer>
Gestión de archivos y Serialización
Cómo serializar un objeto como XMLusing System.Xml.Serialization;public class OrderInfo{
public string OrderId;public DateTime OrderDate;public decimal Cost;internal int ProfitPercent = 75;
}...OrderInfo order = new OrderInfo();order.OrderId = "Order1";order.OrderDate = DateTime.Now;order.Cost = 10.99M;XmlSerializer serializer = new XmlSerializer(typeof(OrderInfo));FileStream xmlStream = new FileStream(@"E:\Democode\order.xml", FileMode.Create,
FileAccess.Write);serializer.Serialize(xmlStream, order);xmlStream.Close();
<?xml version="1.0"?><OrderInfo xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:xsd="http://www.w3.org/2001/XMLSchema"><OrderId>Order1</OrderId><Orderdate>2008-04-01T09:39:13.9010496-08:00</Orderdate><Cost>10.99</Cost>
</OrderInfo>
Cómo serializa datos complejos la clase XmlSerializer
Gestión de archivos y Serialización
Serialización de objetos complejosEl formato XML representa las relaciones entre objetos como una estructura jerárquica de datos.Múltiples referencias generan datos duplicados.
Serialización de colecciones de objetosHay que especificar el tipo de los objetos de la colección al crear el objeto XmlSerializer desde el espacio de nombres System.Xml.Serialization
<?xml version="1.0"?><Person xmlns:xsi="... " > <Name>Francesca</Name> <Id>3</Id> <Father> <Name>John</Name> <Id>1</Id> </Father> <Mother> <Name>Diana</Name> <Id>2</Id> </Mother></Person>
<?xml version="1.0"?><ArrayOfAnyType xmlns:xsi=“..."> <anyType xsi:type="Person"> <Name>Diana</Name> <Id>2</Id> </anyType> <anyType xsi:type="Person"> <Name>John</Name> <Id>1</Id> </anyType> <anyType xsi:type="Person"> <Name>Francesca</Name> <Id>3</Id> <Father> <Name>John</Name> <Id>2</Id> </Father> <Mother> <Name>Diana</Name> <Id>1</Id> </Mother> </anyType></ArrayOfAnyType>
Como especificar definición de tipos XML y espacios de nombres
XmlType(TypeName:="FamilyMember")
Gestión de archivos y Serialización
Atributo que cambia la definición del tipo de una clase cuando se serializa como XMLXmlType
Propiedades comunes de XmlTypeTypeName
Namespace
<?xml version="1.0"?><Person xmlns:xsi="..."> <Name>John</Name> <Id>2</Id></FamilyMember>
<?xml version="1.0"?><Person xmlns:xsi="..."> <Name>John</Name> <Id>2</Id></FamilyMember>
NameId
Person XmlType(TypeName:="FamilyMember", Namespace:="http://adventure-works.com/personnel")
<?xml version="1.0"?><FamilyMember xmlns:xsi="..."> <Name>John</Name> <Id>2</Id></FamilyMember>
<?xml version="1.0"?><FamilyMember xmlns:xsi="..."> <Name>John</Name> <Id>2</Id></FamilyMember>
<?xml version="1.0"?><FamilyMember xmlns:xsi="..."> <Name xmlns="http://adventure-works.com/personnel">John</Name> <Id xmlns="http://adventure-works.com/personnel">2</Id></FamilyMember>
Como controlar la serialización XML para un tipo
Gestión de archivos y Serialización
XmlArrayAttribute
XmlArrayItemAttribute
XmlAttributeAttribute
XmlTextAttribute
XmlIgnoreAttribute
XmlEnumAttribute
XmlElementAttribute
Atributos XMLAtributos para campos, propiedades, parámetros de métodos y valores de retorno
Atributos para tipos
XmlIncludeAttribute
XmlRootAttribute
Como personalizar el proceso de serialización XML
Gestión de archivos y Serialización
Interfaz IXmlSerializableImplementa el método WriteXml con un único parámetro XmlWriter
Escribe XML correctamente formateado mediante los métodos del XmlWriter
BankCustomer()
Public BankCustomer
CustomerName
creditCardPin<?xml version="1.0"><BankCustomer xmlns:xsi="... " > <CustomerName>Fred</CustomerName> <encryptedPin>&^@:%&JA</encryptedPin></BankCustomer>
WriteXml(XmlWriter)
creditCardPin
Como deserializar un objeto desde un Stream XML
Gestión de archivos y Serialización
Uso de la clase XmlSerializer
Crear un objeto XmlSerializer y especificar el tipo de objeto a serializar.
Llamar al método Deserialize y leer datos desde un objeto Stream, TextReader o XmlReader:
Generar el objeto llamando al constructor por defecto Informar sólo los miembros públicos, utilizando los valores
leídos de los datos serializados.
Asegurarse de que los tipos deserializados corresponden al esquema de los datos serializados.
Gestionar los eventos de deserialización para manejar los datos inesperados.
Implementar el método ReadXml del interfaz IXmlSerializable para personalizar el proceso de deserialización XML.