2013-10-11 5 views
0

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

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

Это массив байт, который я буду писать в Cassandra состоит из трех байтовых массивов, как описано

ценам ниже
short employeeId = 32767; 
long lastModifiedDate = "1379811105109L"; 
byte[] attributeValue = os.toByteArray(); 

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

Чтобы сделать это, я использую 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; 

     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(attributeValue); 

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

     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(extractAttributeValue)); 

} 

Есть ли лучший способ сделать это, как я делаю это в настоящее время? Или некоторые незначительные улучшения, которые мы можем сделать здесь?

Это первый раз, когда я использую ByteBuffer таким образом имея мало-мальски проблема ...

Может кто-нибудь посмотрите и дайте мне знать, является ли это правильный способ использовать ByteBuffer?

+1

как вы ожидаете Cassandra, чтобы определить длину 'attributeValue' массива? –

+0

@AlexeiKaigorodov: Я не уверен, я понимаю ваш вопрос .. Кассандре нужно было определить длину массива attributeValue? Нам просто нужно сохранить его, а потом восстановить? – ferhan

ответ

1

Заказ по умолчанию всегда BIG_ENDIAN, поэтому вы не хотите его устанавливать. Также, когда вы завершаете(), это уже перемотка назад() ed.

Вместо копирования базового массива я бы использовал базовый массив.

Заменить

bbuf.rewind(); 

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

с

byte[] bytesToStore = bbuf.array(); 
+0

: Большое спасибо, Питер. Я обязательно сделаю эти изменения ... Есть ли что-нибудь еще, о чем вы думаете, не так? Или вы хотите, чтобы я улучшился? Спасибо за помощь. – ferhan

+0

Вместо использования байта [] и кучи ByteBuffer вы можете использовать прямой ByteBuffer для повышения производительности. –

+0

Извините, я смутился. Можете ли вы привести пример, как сделать это на мой код? Благодарю. – ferhan

Смежные вопросы