使用 readObject/writeObject 反序列化

Posted

技术标签:

【中文标题】使用 readObject/writeObject 反序列化【英文标题】:De-/Serializing with readObject/writeObject 【发布时间】:2015-08-18 20:07:18 【问题描述】:

我对这些 writeObject/readObject 方法有点挣扎。

假设我有一个

trait AbstractPosition
    def file:Path
    def start:String
    def end:String

class SourcePosition(val: Path, val start:String, val end:String)
    extends AbstractPosition
object SourcePosition 
  def apply(file: Path, start: String, end: String) =
    new SourcePosition(file, start, Some(end))

  def unapply(sp: SourcePosition) = Some((sp.file, sp.start, sp.end))

我现在必须将这些职位存储到文件中。天真的尝试失败了,因为 Path 对象不可序列化:

java.io.NotSerializableException: ... .SourcePosition

所以我重写了:

trait AbstractPosition extends Serializable
    def file:Path
    def start:String
    def end:String


class SourcePosition(@transient var fileArg: Path, val start:String, val end:String)
    extends AbstractPosition

  private var fileString :String = null
  override def file: Path = this.fileArg

  @throws(classOf[IOException])
  private def writeObject(out: ObjectOutputStream): Unit = 
    fileString = file.toString
    out.defaultWriteObject()
  

  @throws(classOf[IOException])
  private def readObject(in: ObjectInputStream): Unit = 
    in.defaultReadObject()
    fileArg = Paths.get(fileString)
  
object SourcePosition 
  def apply(file: Path, start: String, end: String) =
    new SourcePosition(file, start, Some(end))

  def unapply(sp: SourcePosition) = Some((sp.file, sp.start, sp.end))

但无济于事:

java.io.NotSerializableException: sun.nio.fs.WindowsPath$WindowsPathWithAttributes

我做错了什么?

我怎样才能实现我想要做的事情?

【问题讨论】:

【参考方案1】:

让你的SourcePosition 成为一个案例类:它是一个完美的候选者,因为它是完全不可变的。默认情况下,case 类是可序列化的,没有所有这些 writeObject/readObject 东西。作为奖励,您将获得由 scalac 自动生成的 apply/unapply 方法。

【讨论】:

假设我从不想要扩展 SourcePosition 的案例类。即便如此,Path 仍然不能被序列化,不是吗? 我错过了路径问题,抱歉。它真的不可序列化。【参考方案2】:

上述方法似乎确实有效。

问题似乎是我忽略了一个val 使用 file。将该 val 更改为 def 允许我序列化 SourcePosition

【讨论】:

以上是关于使用 readObject/writeObject 反序列化的主要内容,如果未能解决你的问题,请参考以下文章

老王讲自制RPC框架.(四.序列化与反序列化)

测试使用

第一篇 用于测试使用

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)