Как избежать исключения BufferOverflow?

Я пытаюсь правильно использовать ByteBuffer с форматом порядка байтов BigEndian.

У меня есть пара полей, которые я пытаюсь объединить в один байтовый буфер, прежде чем сохранять его в базе данных Cassandra.

Этот массив байтов, который я буду записывать в 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)

Теперь я запишу employeeId , lastModifiedDate и быстро сжатое attributeValue вместе в один массив байтов, и этот результирующий массив байтов я запишу в Cassandra, а затем у меня будет моя программа на C++, которая извлечет данные этого массива байтов из Cassandra, а затем десериализую его. чтобы извлечь employeeId , lastModifiedDate и распаковать этот attributeValue с помощью snappy.

Поэтому для этого я использую ByteBuffer с форматом порядка следования байтов BigEndian.

Я собрал этот код вместе -

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, потому что, когда я извлекаю данные из Cassandra из кода C++, они должны быть быстро сжаты, чтобы занимать намного меньше места на нашей карте C++. И распаковать мы его будем только тогда, когда нам позвонят.

Может ли кто-нибудь взглянуть и сообщить мне, что я здесь делаю неправильно? И как мне тогда читать данные?


person AKIWEB    schedule 04.02.2014    source источник
comment
Вы неправильно вычисляете size. Вы действительно не могли понять это из исключения?   -  person kdgregory    schedule 04.02.2014
comment
Но он выдает исключение при сжатии Snappy.compress(attributeValue);?   -  person AKIWEB    schedule 05.02.2014
comment
Навряд ли. Вы видите Snappy где-нибудь в трассировке стека?   -  person kdgregory    schedule 05.02.2014


Ответы (1)


Вы должны использовать длину compressed при выделении исходного байтового буфера.

person jtahlborn    schedule 04.02.2014