Сериализация объекта с помощью Kryo (Custom Serializer)

У меня есть объект, который содержит массив объектов. Я хотел бы

  • А) сохранить этот массив объектов в том же файле

  • B) использовать пользовательскую сериализацию для этих объектов.

Например, у меня есть объект Map с массивом Tile[][]. Я могу делать Ints просто отлично, но запутался в том, как делать объекты:

    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);
        }
    });

person user697111    schedule 26.10.2011    source источник


Ответы (1)


Из вашего примера я могу сказать, что вы используете Kryo v1. Я предлагаю использовать Kryo v2.

Вы можете установить сериализатор для карты, как у вас, а затем сериализовать каждый ключ и значение. Чтобы сериализовать каждый объект, либо запишите данные, используя класс Output, и прочитайте, используя класс Input, либо вызовите методы экземпляра Kryo, чтобы он обрабатывал объекты.

Было бы проще использовать встроенный MapSerializer. Вам нужно только настроить сериализацию ваших объектов Tile. Вы можете попросить их расширить KryoSerializable или зарегистрировать сериализатор. Вот пример...

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);
    }
}

Вот еще один пример использования Serializer вместо 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;
    }
});

Это немного сложнее в методе чтения из-за вызова Kryo#reference перед использованием экземпляра Kryo для десериализации дочерних объектов. Это можно опустить, если вообще не используются ссылки или если вы знаете, что объект something не может ссылаться на плитку, которую мы только что создали. Если бы вы использовали Input только для чтения данных, вам не нужно было бы вызывать Kryo#reference.

person NateS    schedule 15.06.2012