简体   繁体   English

单身对象的Scala序列化/反序列化

[英]Scala serialization/deserialization of singleton object

I am quite new to the scala programming language, and I currently need to do the following. 我对Scala编程语言很陌生,目前需要执行以下操作。 I have a signleton object like the following: 我有一个如下的signleton对象:

object MyObject extends Serializable {
    val map: HashMap[String, Int] = null
    val x: int = -1;
    val foo: String = ""
}

Now i want to avoid to have to serialize each field of this object separately, thus I was considering writing the whole object to a file, and then, in the next execution of the program, read the file and initialize the singleton object from there. 现在,我要避免不必分别序列化此对象的每个字段,因此我正在考虑将整个对象写入文件,然后在程序的下一次执行中,读取文件并从那里初始化单例对象。 Is there any way to do this? 有什么办法吗?

Basically what I want is when the serialization file doesn't exist, those variables to be initialized to new structures, while when it exists, the fields to be initialized from the ones on the file. 基本上我想要的是当序列化文件不存在时,那些变量要初始化为新结构,而当它存在时,要从文件中的字段初始化那些字段。 But I want to avoid having to serialize/deserialize every field manually... 但我想避免手动对每个字段进行序列化/反序列化...

UPDATE: 更新:

I had to use a custom deserializer as presented here: https://issues.scala-lang.org/browse/SI-2403 , since i had issues with a custom class I use inside the HashMap as values. 我必须使用此处提供的自定义反序列化器: https : //issues.scala-lang.org/browse/SI-2403 ,因为我在HashMap中将自定义类用作值时遇到了问题。

UPDATE2: UPDATE2:

Here is the code I use to serialize: 这是我用来序列化的代码:

val store = new ObjectOutputStream(new FileOutputStream(new File("foo"))) 
store.writeObject(MyData) 
store.close

And the code to deserialize (in a different file): 和要反序列化的代码(在另一个文件中):

@transient private lazy val loadedData: MyTrait = {
    if(new File("foo").exists()) {
        val in = new ObjectInputStream(new FileInputStream("foo")) {
            override def resolveClass(desc: java.io.ObjectStreamClass): Class[_] = {
                try { Class.forName(desc.getName, false, getClass.getClassLoader) }
                catch { case ex: ClassNotFoundException => super.resolveClass(desc) }
            }
        }
        val obj = in.readObject().asInstanceOf[MyTrait] 
        in.close
        obj
    }
    else null
}

Thanks, 谢谢,

No needs to serialize an object with only immutable fields (because the compiler will do it for you...) I will assume that the object provides default values. 无需序列化仅具有不可变字段的对象(因为编译器将为您完成此操作...)我将假定该对象提供默认值。 Here is a way to do this: 这是执行此操作的方法:

Start by writing an trait with all the required fields: 首先编写具有所有必填字段的特征:

trait MyTrait {
  def map: HashMap[String, Int]
  def x: Int
  def foo: String
}

Then write an object with the defaults: 然后使用默认值编写一个对象:

object MyDefaults extends MyTrait {
  val map = Map()
  val x = -1
  val foo = 
}

Finally write an implementation unserializing data if it exists: 最后编写一个实现反序列化数据(如果存在)的实现:

object MyData extends MyTrait {

  private lazy val loadedData: Option[MyTrait] = {
     if( /* filename exists */ ) Some( /*unserialize filename as MyTrait*/)
    else None
  }
  lazy val map = loadedData.getOrElse( MyDefault ).map
  lazy val x = loadedData.getOrElse( MyDefault ).x
  lazy val foo = loadedData.getOrElse( MyDefault ).foo

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM