Framework .NET 3.5 14 Gestión de archivos y serialización

51
Índice Gestionando el sistema de archivos Leyendo y escribiendo datos mediante Streams Compresión y protección de datos mediante Streams Ampliando la seguridad de las aplicaciones utilizando almacenamiento aislado. Serialización y Deserialización de objetos mediante Runtime Serialization Personalización de los procesos de Runtime Serialization y Deserialization Serializació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

Transcript of Framework .NET 3.5 14 Gestión de archivos y serialización

Page 1: Framework .NET 3.5 14  Gestión de archivos y serialización

Í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

Page 2: Framework .NET 3.5 14  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

Page 3: Framework .NET 3.5 14  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

Page 4: Framework .NET 3.5 14  Gestión de archivos y serialización

Leer y escribir con la clase File

Gestión de archivos y Serialización

WriteAllBytes

ReadAllBytes

ReadAllLines

ReadAllText

WriteAllLines

WriteAllText

AppendAllText

Page 5: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 6: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 7: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 8: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 9: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 10: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 11: Framework .NET 3.5 14  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

Page 12: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 13: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 14: Framework .NET 3.5 14  Gestión de archivos y serialización

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.

Page 15: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 16: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 17: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 18: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 19: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 20: Framework .NET 3.5 14  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

Page 21: Framework .NET 3.5 14  Gestión de archivos y serialización

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();

}}

Page 22: Framework .NET 3.5 14  Gestión de archivos y serialización

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)

Page 23: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 24: Framework .NET 3.5 14  Gestión de archivos y serialización

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();

Page 25: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 26: Framework .NET 3.5 14  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

Page 27: Framework .NET 3.5 14  Gestión de archivos y serializació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

Page 28: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 29: Framework .NET 3.5 14  Gestión de archivos y serialización

¿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

Page 30: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 31: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 32: Framework .NET 3.5 14  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

Page 33: Framework .NET 3.5 14  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

Page 34: Framework .NET 3.5 14  Gestión de archivos y serialización

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>

Page 35: Framework .NET 3.5 14  Gestión de archivos y serialización

¿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

Page 36: Framework .NET 3.5 14  Gestión de archivos y serialización

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>

Page 37: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 38: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 39: Framework .NET 3.5 14  Gestión de archivos y serialización

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>

Page 40: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 41: Framework .NET 3.5 14  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

Page 42: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 43: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 44: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 45: Framework .NET 3.5 14  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>

Page 46: Framework .NET 3.5 14  Gestión de archivos y serialización

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>

Page 47: Framework .NET 3.5 14  Gestión de archivos y serialización

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>

Page 48: Framework .NET 3.5 14  Gestión de archivos y serialización

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>

Page 49: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 50: Framework .NET 3.5 14  Gestión de archivos y serialización

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

Page 51: Framework .NET 3.5 14  Gestión de archivos y serialización

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.