2009-11-17 9 views
23

Chcę dokonać binarnej serializacji obiektu i wyniku, aby zapisać go w bazie danych.C# Obiekt binarny Serializacja

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

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

Jak mogę przekształcić MemoryStream w typu string być zapisane w bazie danych, a po to, aby móc deserializowania obiekt?

Odpowiedz

48

To, o co się pytasz, to naprawdę bezpieczny sposób reprezentowania dowolnych danych binarnych jako tekstu, a następnie ich ponownej konwersji. Fakt, że przechowuje on obiekt serializowany, jest nieistotny.

Odpowiedź brzmi prawie na użycie Base 64 (np. Convert.ToBase64String i Convert.FromBase64String). Czy nie użyć Encoding.UTF8.GetString lub coś podobnego - twoje dane binarne są nie zakodowanych danych tekstowych i nie powinny być traktowane jako takie.

Jednak czy baza danych nie ma typu danych dla danych binarnych? Sprawdź, BLOB, Obraz i binarne typy ...

+0

bajtów ciąg --- potrzebuje kodowania. – loneshark99

+0

@ loneshark99: W ogóle nie rozumiem twojego komentarza. Jeśli jest to arbitralne dane binarne - zamiast zakodowanego tekstu - użycie "kodowania" byłoby właśnie błędnym * podejściem. –

+0

Uczę się, ale zastanawiam się, dlaczego kodowanie nie jest właściwym podejściem, a ToBase64String jest. – loneshark99

8

Kiedyś coś jak ten

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

Nie trzeba przewijać obiektu MemoryStream przed wywołaniem ToArray - zwraca dane całego strumienia niezależnie od aktualnej pozycji. Podobnie Flush nie robi nic na MemoryStream, chociaż jest to dobry pomysł na strumienie w ogóle. –

+0

Dzięki za radę. –

2

Zasadniczo nie zapisać dane jako ciąg do bazy danych, istnieje blob pola dostępne do sklepu dane binarne.

Jeśli naprawdę potrzebujesz danych jako ciągów, musisz przekonwertować bajt [] na ciąg znaków przy użyciu kodowania base64 i pobrać bajt [] z dekodowania za pomocą ciągu znaków.

0

Nie sprawdziłeś, czy konwersja strumienia pamięci w ciąg 64-znakowy należy wprowadzić do bazy danych?

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

Następnie można zrzucić zawartość sConvertdHex do bazy danych. Aby deserializować go, musisz odwrotnie wykonać odwrotne przekształcenie mData z powrotem na swój obiekt.

32

Oto próbka. TData musi być oznaczony [Serializable], a wszystkie pola również typu.

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

Powinno być 'użycie' wokół' MemoryStream' – j00hi