2014-09-21 9 views
10

Chciałbym móc używać wytrawiania scala w celu przechowywania reprezentacji binarnej klasy case.Scala klasy picklingowania wersji

chciałbym wiedzieć, czy istnieje sposób, aby zarządzać wersjonowanie klasy etui (bufor protokół sposób pozwala zrobić)


Oto mój przykład

Robię program o pewna data, o następującej klasie przypadku

case class MessageTest(a:String,b:String) 

Potem serializacji instancji tej klasy

import scala.pickling._ 
import binary._ 
val bytes=MessageTest("1","2").pickle 

I wtedy zapisać wynik do pliku


Później mogę teraz zrobić ewolucję na mojej klasie przypadku, aby dodać nowe pole opcjonalnego

case class MessageTest (a:String,b:String,c:Option[String]=None) 

I chciałbym móc ponownie wykorzystać dane, które zapisałem wcześniej w moim pliku, deserializować go i móc odzyskać instancję klasy sprawy (z wartością domyślną dla nowego parametru)

Ale kiedy użyć następującego kodu

import scala.pickling._ 
import binary._ 
val messageback=bytes.unpickle[MessageTest] 

mam następujący błąd:

java.lang.ArrayIndexOutOfBoundsException: 26 na scala.pickling.binary.BinaryPickleReader $$ anonfun $ 2.apply (BinaryPickleFormat .scala: 446) na scala.pickling.binary.BinaryPickleReader $$ anonfun $ 2.apply (BinaryPickleFormat.scala: 434) na scala.pickling.PickleTools $ class.withHints (Tools.scala: 498) na scala.pickling .binary.BinaryPickleReader.withHints (BinaryPickleFormat.scala: 425) w scala.pickling.binary.BinaryPickleReader.beginEntryNoTagDebug (BinaryPickleFormat.scala: 434) na scala.pickling.binary.BinaryPickleReader.beginEntryNoTag (BinaryPickleFormat.scala: 431)


zrobiłem coś złego?

Czy istnieje sposób, aby mój scenariusz zadziałał?

Pozdrowienia

+0

Co za cisza ... Mam to samo pytanie, @Fred czy znalazłeś rozwiązanie? – Emer

+0

Rozważamy zastosowanie typu 'Map' jako obejścia. http://docs.scala-lang.org/overviews/collections/maps – Emer

Odpowiedz

0

Dobrze problem jest to, że starają się deserializowania powrotem do innego obiektu niż to, co się w odcinkach.

Rozważ to. Pierwszy obiekt:

scala> case class MessageTest(a: String, b:String) 
defined class MessageTest 

scala> val bytes = MessageTest("a", "b").pickle 
bytes: pickling.binary.pickleFormat.PickleType = BinaryPickle([0,0,0,81,36,108,105,110,101,53,49,46,36,114,101,97,100,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,77,101,115,115,97,103,101,84,101,115,116,0,0,0,1,97,0,0,0,1,98]) 

Teraz ze zmienionym obiektem przypadku ...

scala> case class MessageTest(a: String, b: String, c: Option[String] = None) 
defined class MessageTest 

scala> val bytes = MessageTest("a", "b").pickle 
bytes: pickling.binary.pickleFormat.PickleType = BinaryPickle([0,0,0,81,36,108,105,110,101,53,51,46,36,114,101,97,100,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,36,105,119,46,77,101,115,115,97,103,101,84,101,115,116,0,0,0,1,97,0,0,0,1,98,0,0,0,15,115,99,97,108,97,46,78,111,110,101,46,116,121,112,101]) 

Nie ma sposobu, aby biblioteka mogła wiedzieć, co masz na myśli w tym przypadku, ponieważ spodziewa się, że podpisy będą pasować.

https://github.com/scala/pickling/issues/39 ale możesz przynajmniej przejść w jedną stronę. jak pokazano tutaj.

import scala.pickling._ 
import scala.pickling.Defaults._ 
import scala.pickling.binary._ 

case class LegacyMessage(a: String, b: String) 
case class Message(a: String, b: String, c: Option[String] = None) 

implicit val legacyUnpickler = Unpickler.generate[LegacyMessage] 
implicit val messageUnpickler = Unpickler.generate[Message] 

val legacyBytes = LegacyMessage("a", "b") 
val msgBytes = Message("a", "b", None) 

val pickledBytes = msgBytes.pickle 
val pickledLegacy = legacyBytes.pickle 

// New Message can Serialize back to Legacy Messages 
val newToOld = pickledBytes.unpickle[LegacyMessage] 

// Old Messages can not serialize up to the new message schema 
// println(pickledLegacy.unpickle[Message]) 

val old = pickledLegacy.unpickle[LegacyMessage] 

if(newToOld == old){ 
    println(true) 
} 

Mam nadzieję, że to trochę pomaga.

Powiązane problemy