2009-11-17 29 views
23

Quiero hacer una serialización binaria de un objeto y el resultado para guardarlo en una base de datos.C# Serialización binaria de objetos

Person person = new Person(); 
person.Name = "something"; 

MemoryStream memorystream = new MemoryStream(); 
BinaryFormatter bf = new BinaryFormatter(); 
bf.Serialize(memorystream, person); 

¿Cómo puedo transformar MemoryStream en un tipo de cadena para ser guardado en la base de datos, y después de esto para poder deserializar el objeto?

Respuesta

48

Lo que está Realmente pedir es una manera segura de representar datos binarios arbitrarios como texto y luego convertirlos de nuevo. El hecho de que almacene un objeto serializado es irrelevante.

La respuesta es casi utilizar Base 64 (por ejemplo, Convert.ToBase64String y Convert.FromBase64String). Do no use Encoding.UTF8.GetString o algo similar - sus datos binarios son no datos de texto codificados, y no deben tratarse como tales.

Sin embargo, ¿su base de datos no tiene un tipo de datos binarios? Comprobar si hay BLOB, Imagen y tipos binarios ...

+0

bytes a cadena --- necesita un poco de codificación. – loneshark99

+0

@ loneshark99: No entiendo tu comentario en absoluto. Si se trata de datos binarios arbitrarios, en lugar de texto codificado, el uso de 'Codificación 'sería precisamente el enfoque * incorrecto *. –

+0

Estoy aprendiendo, pero me pregunto por qué la codificación no es el enfoque correcto y ToBase64String sí lo es. – loneshark99

8

he usado algo como esto

MemoryStream memoryStream = new MemoryStream(); 
BinaryFormatter binaryFormatter = new BinaryFormatter(); 
binaryFormatter.Serialize(memoryStream, Person); 
memoryStream.Flush(); 
memoryStream.Position = 0; 
string value = Convert.ToBase64String(memoryStream.ToArray()); 
+8

No necesita rebobinar un MemoryStream antes de llamar a ToArray: devuelve los datos de toda la secuencia, independientemente de la posición actual. Del mismo modo, Flush no hace nada en un MemoryStream, aunque es una buena idea para las transmisiones en general. –

+0

Gracias por el consejo. –

2

Básicamente, no guardar los datos como cadena a la base de datos, hay blob campos disponibles para tienda datos binarios.

Si realmente necesita tener los datos como una cadena, necesitará convertir su byte [] a una cadena usando la codificación base64, y para tomar el byte [] de una cadena use decodificación.

0

¿No ha considerado la posibilidad de convertir el flujo de memoria en una cadena de base64hex para poner en la base de datos?

byte[] mStream = memorystream.ToArray(); 
string sConvertdHex = System.Convert.ToBase64String(mStream) 

A continuación, puede volcar los contenidos sConvertdHex en la base de datos. Deserializar lo que hay que hacer a la inversa

byte[] mData = System.Convert.FromBase64String(...) 

continuación, deserializar MDATA de nuevo a su objeto.

32

Aquí está la muestra. TData debe marcarse [Serializable] y todos los campos escribir también.

private static TData DeserializeFromString<TData>(string settings) 
    { 
     byte[] b = Convert.FromBase64String(settings); 
     using (var stream = new MemoryStream(b)) 
     { 
      var formatter = new BinaryFormatter(); 
      stream.Seek(0, SeekOrigin.Begin); 
      return (TData)formatter.Deserialize(stream); 
     } 
    } 

    private static string SerializeToString<TData>(TData settings) 
    { 
     using (var stream = new MemoryStream()) 
     { 
      var formatter = new BinaryFormatter(); 
      formatter.Serialize(stream, settings); 
      stream.Flush(); 
      stream.Position = 0; 
      return Convert.ToBase64String(stream.ToArray()); 
     } 
    } 
16
 //-------write to database------------------------- 
     Person person = new Person(); 
     person.name = "Firstnm Lastnm"; 
     MemoryStream memorystream = new MemoryStream(); 
     BinaryFormatter bf = new BinaryFormatter(); 
     bf.Serialize(memorystream, person); 
     byte[] yourBytesToDb = memorystream.ToArray(); 
     //here you write yourBytesToDb to database 


     //----------read from database--------------------- 
     //here you read from database binary data into yourBytesFromDb 
     MemoryStream memorystreamd = new MemoryStream(yourBytesFromDb); 
     BinaryFormatter bfd = new BinaryFormatter(); 
     Person deserializedperson = bfd.Deserialize(memorystreamd) as Person; 
+1

Debería haber un 'uso' alrededor del' MemoryStream' – j00hi

Cuestiones relacionadas