如何正确使用 ByteBuffer?
Posted
技术标签:
【中文标题】如何正确使用 ByteBuffer?【英文标题】:How to use ByteBuffer properly? 【发布时间】:2013-10-11 06:27:17 【问题描述】:我正在尝试以 BigEndian 字节顺序格式正确使用 ByteBuffer..
在将其存储到 Cassandra 数据库之前,我尝试将几个字段组合到一个 ByteBuffer 中。
我将写入 Cassandra 的字节数组由三个字节数组组成,如下所述-
short employeeId = 32767;
long lastModifiedDate = "1379811105109L";
byte[] attributeValue = os.toByteArray();
现在,我将 employeeId
、 lastModifiedDate
和 attributeValue
一起写入单个字节数组,然后将生成的字节数组写入 Cassandra,然后我将拥有我的 C++ 程序,该程序将检索该字节数组来自 Cassandra 的数据,然后对其进行反序列化以从中提取 employeeId
、lastModifiedDate
和 attributeValue
。
为此,我使用了具有 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;
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 的正确方法?
【问题讨论】:
你希望Cassandra如何确定attributeValue
数组的长度?
@AlexeiKaigorodov :我不确定,我理解你的问题.. cassandra 是否需要确定 attributeValue 数组的长度?我们只需要存储它然后检索它?
【参考方案1】:
默认顺序始终为 BIG_ENDIAN,因此您不必设置它。此外,当您 wrap() 时已经 rewind() 了。
我不会复制底层数组,而是使用底层数组。
替换
bbuf.rewind();
// best approach is copy the internal buffer
byte[] bytesToStore = new byte[size];
bbuf.get(bytesToStore);
与
byte[] bytesToStore = bbuf.array();
【讨论】:
:非常感谢 Peter.. 我一定会做出这些改变...您认为还有什么不正确的吗?还是想让我改进?感谢您的帮助.. 您可以直接使用 ByteBuffer 来提高性能,而不是使用 byte[] 和堆 ByteBuffer。 对不起,我很困惑..你能提供一个例子,如何根据我的代码做到这一点吗?谢谢。 @TechGeeky 除非 Cassandra 支持直接缓冲区,否则我不会打扰,因为它无济于事。 对此我不确定,但我想现在没问题。还有一件事,反序列化部分怎么样?我们是否也需要做出任何改变?还是反序列化部分看起来不错。?谢谢..以上是关于如何正确使用 ByteBuffer?的主要内容,如果未能解决你的问题,请参考以下文章
Netty基础必备知识,ByteBuffer和ByteBuf底层原理
Netty基础必备知识,ByteBuffer和ByteBuf底层原理