java - 如何避免 BufferOverflow 异常?

标签 java bytebuffer avro

我正在尝试通过 BigEndian 字节顺序格式正确使用 ByteBuffer..

在将其存储到 Cassandra 数据库之前,我试图将几个字段放在一个 ByteBuffer 中。

我将写入 Cassandra 的字节数组由三个字节数组组成,如下所述-

short employeeId = 32767;
long lastModifiedDate = "1379811105109L";
byte[] attributeValue = os.toByteArray();

现在我需要快速压缩 attributeValue 数据,然后再将其存储到 Cassandra -

employeeId (do not snappy compressed)
lastModifiedDate (do not snappy compressed)
attributeValue  (snappy compressed it)

现在,我将把 employeeIdlastModifiedDate 和 snappy 压缩的 attributeValue 一起写入一个字节数组,然后我将编写生成的字节数组进入 Cassandra,然后我将拥有我的 C++ 程序,该程序将从 Cassandra 检索字节数组数据,然后将其反序列化以提取 employeeIdlastModifiedDate 并解压缩此 attributeValue 从中使用 snappy。

为此,我使用了 BigEndian 字节顺序格式的 ByteBuffer。

我已经把这段代码放在一起了-

public static void main(String[] args) throws Exception {

        String text = "Byte Buffer Test";
        byte[] attributeValue = text.getBytes();

        long lastModifiedDate = 1289811105109L;
        short employeeId = 32767;

        // snappy compressing it and this line gives BufferOverflowException
        byte[] compressed = Snappy.compress(attributeValue);

        int size = 2 + 8 + 4 + attributeValue.length; // short is 2 bytes, long 8 and int 4

        ByteBuffer bbuf = ByteBuffer.allocate(size); 

        bbuf.order(ByteOrder.BIG_ENDIAN);
        bbuf.putShort(employeeId);
        bbuf.putLong(lastModifiedDate);
        bbuf.putInt(attributeValue.length);
        bbuf.put(compressed); // storing the snappy compressed data

        bbuf.rewind();

        // best approach is copy the internal buffer
        byte[] bytesToStore = new byte[size];
        bbuf.get(bytesToStore);

        // write bytesToStore in Cassandra...

        // Now retrieve the Byte Array data from Cassandra and deserialize it...
        byte[] allWrittenBytesTest = bytesToStore;//magicFunctionToRetrieveDataFromCassandra();

        // I am not sure whether the below read code will work fine or not..
        ByteBuffer bb = ByteBuffer.wrap(allWrittenBytesTest);

        bb.order(ByteOrder.BIG_ENDIAN);
        bb.rewind();

        short extractEmployeeId = bb.getShort();
        long extractLastModifiedDate = bb.getLong();
        int extractAttributeValueLength = bb.getInt();
        byte[] extractAttributeValue = new byte[extractAttributeValueLength];

        bb.get(extractAttributeValue); // read attributeValue from the remaining buffer

        System.out.println(extractEmployeeId);
        System.out.println(extractLastModifiedDate);
        System.out.println(new String(Snappy.uncompress(extractAttributeValue)));

}

上面的代码以某种方式抛出 BufferOverflowException -

Exception in thread "main" java.nio.BufferOverflowException
    at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:165)
    at java.nio.ByteBuffer.put(ByteBuffer.java:813)

为什么我在将数据存储到 Cassandra 之前快速压缩数据,因为当我从 C++ 代码从 Cassandra 检索数据时,它应该快速压缩,这样它在我们的 C++ 映射中占用的空间就会少很多。只有当人们调用我们时,我们才会解压缩它。

任何人都可以看一下,让我知道我在这里做错了什么吗?那我应该如何读取数据呢?

最佳答案

分配原始 ByteBuffer 时,您应该使用压缩的长度。

关于java - 如何避免 BufferOverflow 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21561760/

相关文章:

java - 使用 Java 将数据动态插入 Excel 中

java - 读取 5 个字节并存储为 long

apache-kafka - 有没有办法将数据从 InfluxDB 发送到 Kafka?

java - 如何将 apache avro GenericRecord 用于动态数据?

java - 线程中出现异常 "main"java.lang.UnsatisfiedLinkError : sample. HelloWorld.print()V

java - Android 根据国家/地区运行不同的功能

java - 在java中向数组添加新元素从左向右移动一步

java - 大型 ByteBuffer 的 BufferedReader?

java - Java GC 如何清理直接字节缓冲区,因为 IBM 文档说,确实如此。

scala - Spark : Writing to Avro file