2

给定一个同质类型对象流,我将如何将它们序列化为二进制,将它们写入磁盘,从磁盘读取它们,然后使用 Scala Pickling 反序列化它们?

例如:

object PicklingIteratorExample extends App {

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

    case class Person(name: String, age: Int)

    val personsIt = Iterator.from(0).take(10).map(i => Person(i.toString, i))
    val pklsIt = personsIt.map(_.pickle)

    ??? // Write to disk
    val readIt: Iterator[Person] = ??? // Read from disk and unpickle
} 
4

1 回答 1

1

我为标准文件找到了一种方法:

object PickleIOExample extends App {
    import scala.pickling.Defaults._
    import scala.pickling.binary._
    import scala.pickling.static._

    val tempPath = File.createTempFile("pickling", ".gz").getAbsolutePath
    val outputStream = new FileOutputStream(tempPath) 
    val inputStream = new FileInputStream(tempPath) 

    val persons = for{
        i <- 1 to 100
    } yield Person(i.toString, i)

    val output = new StreamOutput(outputStream)
    persons.foreach(_.pickleTo(output))
    outputStream.close()

    val personsIt = new Iterator[Person]{
        val streamPickle = BinaryPickle(inputStream)

        override def hasNext: Boolean = inputStream.available > 0

        override def next(): Person = streamPickle.unpickle[Person]
    }

    println(personsIt.mkString(", "))
    inputStream.close()
}

但我仍然无法找到适用于 gzip 文件的解决方案。既然不知道怎么检测EOF呢?由于 GZIPInputStream 可用方法不指示 EOF,因此以下引发 EOF 异常:

object PickleIOExample extends App {
    import scala.pickling.Defaults._
    import scala.pickling.binary._
    import scala.pickling.static._

    val tempPath = File.createTempFile("pickling", ".gz").getAbsolutePath
    val outputStream = new GZIPOutputStream(new FileOutputStream(tempPath))
    val inputStream = new GZIPInputStream(new FileInputStream(tempPath))

    val persons = for{
        i <- 1 to 100
    } yield Person(i.toString, i)

    val output = new StreamOutput(outputStream)
    persons.foreach(_.pickleTo(output))
    outputStream.close()

    val personsIt = new Iterator[Person]{
        val streamPickle = BinaryPickle(inputStream)

        override def hasNext: Boolean = inputStream.available > 0

        override def next(): Person = streamPickle.unpickle[Person]
    }

    println(personsIt.mkString(", "))
    inputStream.close()
}
于 2015-06-09T13:39:55.803 回答