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

标签 java serialization oracle11g blob kryo

我正在尝试使用 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?我应该如何处理大于 max 尺寸的非常大的物体。字节数组?
  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();
}

最佳答案

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

try (Output output = new Output(blob.setBinaryStream(0L))) {
    ....
}

关于java - 如何使用 Kryo 将非常大的 Java 对象保存到 Oracle 中的 Blob 中并避免 KryoException 缓冲区溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49906504/

相关文章:

c# - 自定义 XML 序列化添加额外的属性

linux - unixODBC 产生 ORA-12154 TNS 解析错误,而 sqlplus 工作正常

serialization - Dart的built_value库,如何在flutter中生成serializer文件?

java - 启用对象映射器 writeValueAsString 方法以包含空值

java - 是否可以检查方法是否在一组类中声明?

Java GUI 布局建议

json - ETL - 自动将数据从一个数据库传输到另一个数据库

oracle - 在 Oracle SQL LOAD 期间未正确插入欧元 '€' 符号

java - 使用切换按钮设置警报通知 - Android

java - 如何遍历屏幕上显示的所有组件