如何使用Kryo将非常大的Java对象保存到Oracle中的Blob并避免KryoException缓冲区溢出?

问题描述 投票:1回答:1

我想用Kryo保存一个非常大的物体,

public static byte[] toBytes(KryoPool kryoPool, Object object) {
    try (Output output = new Output(32768, Integer.MAX_VALUE - 8)) {
        kryoPool.run(kryo -> {
            kryo.setReferences(false);
            kryo.writeObject(output, object);
            return null;
        });
        return output.toBytes();
    }
}

我得到例外:

com.esotericsoftware.kryo.KryoException: Buffer overflow. Available: 0, required: 1
    at com.esotericsoftware.kryo.io.Output.require(Output.java:167)
    at com.esotericsoftware.kryo.io.Output.writeByte(Output.java:225)
    at com.esotericsoftware.kryo.Kryo.writeObjectOrNull(Kryo.java:623)
    at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:86)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:508)
    at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:651)
    at com.esotericsoftware.kryo.serializers.CollectionSerializer.write(CollectionSerializer.java:100)
    at com.esotericsoftware.kryo.serializers.CollectionSerializer.write(CollectionSerializer.java:40)
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:575)
    at com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:79)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:508)
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:557)

然后应将此字节数组保存到Oracle表Blob字段中。我现在意识到两件事:

  1. byte []的大小有限,不能大于2 ^ 31-1?我应该如何处理大于最大尺寸的非常大的物体。字节数组?
  2. 如何避免Kryo Buffer溢出异常?

更新:非常感谢。我只是想知道我应该在哪个方面调用Kryo序列化:

    try (final PreparedStatement pstmt = conn.prepareStatement("INSERT INTO DATA_STORAGE (ID, VALUE) VALUES (?, ?)")) 
{
        final Blob blob = conn.createBlob();
        OutputStream out = blob.setBinaryStream(0L);

        Output output = new Output(out);

        pstmt.setInt(1, id);
        pstmt.setBlob(2, blob);

        //probably here?   
        kryoPool.run(kryo -> {
            kryo.setReferences(false);
            kryo.writeObject(output, object);
            return null;
        });

        pstmt.executeUpdate();
}
java serialization oracle11g blob kryo
1个回答
1
投票

不要创建中间byte[],而是直接流到BLOB:

try (Output output = new Output(blob.setBinaryStream(0L))) {
    ....
}
© www.soinside.com 2019 - 2024. All rights reserved.