Kotlin Object Serialization

Whenever a class implements Serializable, it’s a candidate for object serialization. The serialization mechanism converts an object into bytes and then writes the object to the output stream. We use the class ObjectOutputStream to serialize a file and then ObjectInputStream to restore an object.

import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.ObjectInputStream
import java.io.ObjectOutputStream

fun main(args : Array<String>){
    //Destination File
    val file = "belchers.burgers"

    //A map of family
    val family = mapOf(
            "Bob" to "Father",
            "Linda" to "Mother",
            "Tina" to "Oldest",
            "Gene" to "Middle",
            "Louise" to "Youngest")

    //Write the family map object to a file
    ObjectOutputStream(FileOutputStream(file)).use{ it -> it.writeObject(family)}

    println("Wrote $file")
    println()
    println("Time to read $file back")

    //Now time to read the family back into memory
    ObjectInputStream(FileInputStream(file)).use { it ->
        //Read the family back from the file
        val restedFamily = it.readObject()

        //Cast it back into a Map
        when (restedFamily) {
            //We can't use <String, String> because of type erasure
            is Map<*, *> -> println(restedFamily)
            else -> println("Deserialization failed")
        }
    }
}

The example program writes a map of strings to a file using object serialization. It begins by creating a map of test data on lines 11-16. Line 19 opens the file by creating a FileOutputStream object and passing in the file name to the constructor. The FileOutputStream object gets passed to the newly created ObjectOutputStream. We apply the use() function to make sure all resources are closed when finished.

Writing the map to the file is painless. All we need to do is use the writeObject() method found on ObjectOutputStream, shown on line 19. The class does all of the work of flattening the family Map object into bytes and writing the bytes to the file. The use() function closes the file and the serialization process is complete.

Reading the object back into memory is almost as simple. We open the file by creating a new FileInputStream object and supplying the constructor with the file name. The FileInputStream object is supplied to the constructor of the ObjectInputStream and we chain it to the use() function to make sure the file gets closed when finished.

The object is restored with the readObject() method, but there is a catch. The readObject() method returns Any. It’s our job to downcast to the proper type. On line 31, we use the when() function and on line 33, we check that it is a Map. Since map is a generic interface and serialization doesn’t save type, we use *, * for the type arguments. At this point, we can work on the restedFamily object normally.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: