2009-11-17 3 views
23

Desidero creare un serialize binario di un oggetto e il risultato per salvarlo in un database.Serializzazione binaria degli oggetti C#

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

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

Come posso trasformare MemoryStream in un tipo stringa da salvare nel database, e dopo questo per essere in grado di deserializzare l'oggetto?

risposta

48

Quello che stai in realtà chiedere è un modo sicuro di rappresentare dati binari arbitrari come testo e quindi riconvertirli di nuovo. Il fatto che memorizzi un oggetto serializzato è irrilevante.

La risposta è quasi utilizzare Base 64 (ad esempio Convert.ToBase64String e Convert.FromBase64String). Fare non utilizzare Encoding.UTF8.GetString o qualcosa di simile - i dati binari sono non dati di testo codificati e non devono essere trattati come tali.

Tuttavia, il database non ha un tipo di dati per i dati binari? Verificare la presenza di BLOB, immagine e tipi binario ...

+0

byte a stringa --- bisogno di qualche codifica. – loneshark99

+0

@ loneshark99: non capisco il tuo commento. Se si tratta di dati binari arbitrari - piuttosto che di testo codificato - allora l'uso di un 'Encoding' sarebbe proprio l'approccio * errato *. –

+0

Sto imparando, ma mi chiedo perché Encoding non è l'approccio giusto e ToBase64String è. – loneshark99

8

Ho usato qualcosa di simile

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

Non è necessario riavvolgere un MemoryStream prima di chiamare ToArray - restituisce i dati dell'intero flusso indipendentemente dalla posizione corrente. Allo stesso modo Flush non fa nulla su MemoryStream, sebbene sia una buona idea per i flussi in generale. –

+0

Grazie per il consiglio. –

2

In sostanza, non salvare i dati come stringa al database, ci sono blob campi disponibili al negozio dati binari.

Se è davvero necessario avere i dati come stringa, è necessario convertire il byte [] in una stringa utilizzando la codifica base64 e per afferrare il byte [] da una stringa utilizzare la decodifica.

0

Non hai esaminato la conversione del memorandum in una stringa base64hex da inserire nel database?

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

Quindi è possibile scaricare il contenuto sConvertdHex nel database. Per deserializzare esso è necessario fare il contrario

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

poi deserializzare mData di nuovo al vostro oggetto.

32

Ecco il campione. TData deve essere contrassegnato [Serializable] e anche tutti i campi.

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

Ci dovrebbe essere un 'uso' attorno a' MemoryStream' – j00hi