Serialization of an object with Kryo (Custom Serializer)

16,708

I can tell from your example that you are using Kryo v1. I suggest using Kryo v2.

You can set a serializer for Map, like you have, and then serialize each key and value. To serialize each object, either write the data using the Output class and read using the Input class, or call methods on the Kryo instance to have it handle the objects.

It would be easier to use the built in MapSerializer. You only need to customize serialization of your Tile objects. You can have them extend KryoSerializable or you can register a Serializer. Here is an example...

public class Tile implements KryoSerializable {
    int x, y;
    Object something;

    public void write (Kryo kryo, Output output) {
        output.writeInt(x);
        output.writeInt(y);
        kryo.writeClassAndObject(output, something);
    }

    public void read (Kryo kryo, Input input) {
        x = input.readInt();
        y = input.readInt();
        something = kryo.readClassAndObject(input);
    }
}

Here is another example, using a Serializer instead of KryoSerializable:

public class Tile {
    int x, y;
    Object something;
}

kryo.register(Tile.class, new Serializer<Tile>() {
    public void write (Kryo kryo, Output output, Tile object) {
        output.writeInt(object.x);
        output.writeInt(object.y);
        kryo.writeClassAndObject(output, object.something);
    }

    public Tile read (Kryo kryo, Input input, Class<Tile> type) {
        Tile tile = new Tile();
        kryo.reference(tile); // Only necessary if Kryo#setReferences is true AND Tile#something could reference this tile.
        tile.x = input.readInt();
        tile.y = input.readInt();
        tile.something = kryo.readClassAndObject(input);
        return tile;
    }
});

This is slightly more complicated in the read method because of the call to Kryo#reference before you use the Kryo instance to deserialize child objects. This can be omitted if not using references at all, or if you know that the "something" object cannot possibly reference the tile we have just created. If you were only using Input to read data, you wouldn't need to call Kryo#reference.

Share:
16,708
user697111
Author by

user697111

Updated on September 07, 2022

Comments

  • user697111
    user697111 over 1 year

    I have an object which contains an array of objects. I would like to

    • A) store this array of objects in the same file

    • B) use custom serialization for those objects.

    For example, I have a Map object which has Tile[][] array. I can do Ints just fine, but confused on how to do objects:

        kryo.register(Map.class, new SimpleSerializer<Map>() {
            public void write(ByteBuffer buffer, Map map) {
    
                buffer.putInt(map.getId());
                System.out.println("Putting: " + map.getId());
    
    
            }
    
            public Map read(ByteBuffer buffer) {
                int id = buffer.getInt();
                System.out.println("Getting: " + id);
    
                Map map = new Map(id, null, 0, 0, 0, 0);
    
                return (map);
            }
        });