我有一个标题和数据,我需要在一个表示Byte Array
.我有一种特殊的格式用于打包标题Byte Array
,也可以采用不同的格式打包数据Byte Array
.在我拥有这两个之后,我需要做出最后一个Byte Array
.
下面是布局,它是如何定义的C++
,因此我必须做Java
.
// below is my header offsets layout // addressedCenter must be the first byte static constexpr uint32_t addressedCenter = 0; static constexpr uint32_t version = addressedCenter + 1; static constexpr uint32_t numberOfRecords = version + 1; static constexpr uint32_t bufferUsed = numberOfRecords + sizeof(uint32_t); static constexpr uint32_t location = bufferUsed + sizeof(uint32_t); static constexpr uint32_t locationFrom = location + sizeof(CustomerAddress); static constexpr uint32_t locationOrigin = locationFrom + sizeof(CustomerAddress); static constexpr uint32_t partition = locationOrigin + sizeof(CustomerAddress); static constexpr uint32_t copy = partition + 1; // this is the full size of the header static constexpr uint32_t headerOffset = copy + 1;
并且CustomerAddress
是一个typedef uint64_t
,它是这样组成的 -
typedef uint64_t CustomerAddress; void client_data(uint8_t datacenter, uint16_t clientId, uint8_t dataId, uint32_t dataCounter, CustomerAddress& customerAddress) { customerAddress = (uint64_t(datacenter) << 56) + (uint64_t(clientId) << 40) + (uint64_t(dataId) << 32) + dataCounter; }
以下是我的数据布局 -
// below is my data layout - // // key type - 1 byte // key len - 1 byte // key (variable size = key_len) // timestamp (sizeof uint64_t) // data size (sizeof uint16_t) // data (variable size = data size)
问题陈述:-
现在对于项目的一部分,我试图在Java中的一个特定类中表示整体内容,以便我可以传递必要的字段,它可以使我成为最后Byte Array
一个,首先是头,然后是数据:
以下是我的DataFrame
课程:
public final class DataFrame { private final byte addressedCenter; private final byte version; private final MapkeyDataHolder; private final long location; private final long locationFrom; private final long locationOrigin; private final byte partition; private final byte copy; public DataFrame(byte addressedCenter, byte version, Map keyDataHolder, long location, long locationFrom, long locationOrigin, byte partition, byte copy) { this.addressedCenter = addressedCenter; this.version = version; this.keyDataHolder = keyDataHolder; this.location = location; this.locationFrom = locationFrom; this.locationOrigin = locationOrigin; this.partition = partition; this.copy = copy; } public byte[] serialize() { // All of the data is embedded in a binary array with fixed maximum size 70000 ByteBuffer byteBuffer = ByteBuffer.allocate(70000); byteBuffer.order(ByteOrder.BIG_ENDIAN); int numOfRecords = keyDataHolder.size(); int bufferUsed = getBufferUsed(keyDataHolder); // 36 + dataSize + 1 + 1 + keyLength + 8 + 2; // header layout byteBuffer.put(addressedCenter); // byte byteBuffer.put(version); // byte byteBuffer.putInt(numOfRecords); // int byteBuffer.putInt(bufferUsed); // int byteBuffer.putLong(location); // long byteBuffer.putLong(locationFrom); // long byteBuffer.putLong(locationOrigin); // long byteBuffer.put(partition); // byte byteBuffer.put(copy); // byte // now the data layout for (Map.Entry entry : keyDataHolder.entrySet()) { byte keyType = 0; byte keyLength = (byte) entry.getKey().length; byte[] key = entry.getKey(); byte[] data = entry.getValue(); short dataSize = (short) data.length; ByteBuffer dataBuffer = ByteBuffer.wrap(data); long timestamp = 0; if (dataSize > 10) { timestamp = dataBuffer.getLong(2); } byteBuffer.put(keyType); byteBuffer.put(keyLength); byteBuffer.put(key); byteBuffer.putLong(timestamp); byteBuffer.putShort(dataSize); byteBuffer.put(data); } return byteBuffer.array(); } private int getBufferUsed(final Map keyDataHolder) { int size = 36; for (Map.Entry entry : keyDataHolder.entrySet()) { size += 1 + 1 + 8 + 2; size += entry.getKey().length; size += entry.getValue().length; } return size; } }
以下是我使用上述DataFrame
课程的方式:
public static void main(String[] args) throws IOException { // header layout byte addressedCenter = 0; byte version = 1; long location = packCustomerAddress((byte) 12, (short) 13, (byte) 32, (int) 120); long locationFrom = packCustomerAddress((byte) 21, (short) 23, (byte) 41, (int) 130); long locationOrigin = packCustomerAddress((byte) 21, (short) 24, (byte) 41, (int) 140); byte partition = 3; byte copy = 0; // this map will have key as the actual key and value as the actual data, both in byte array // for now I am storing only two entries in this map MapkeyDataHolder = new HashMap (); for (int i = 1; i <= 2; i++) { keyDataHolder.put(generateKey(), getMyData()); } DataFrame records = new DataFrame(addressedCenter, version, keyDataHolder, location, locationFrom, locationOrigin, partition, copy); // this will give me final packed byte array // which will have header and data in it. byte[] packedArray = records.serialize(); } private static long packCustomerAddress(byte datacenter, short clientId, byte dataId, int dataCounter) { return ((long) (datacenter) << 56) | ((long) clientId << 40) | ((long) dataId << 32) | ((long) dataCounter); }
正如你在我的DataFrame
课堂上看到的那样,我正在分配ByteBuffer
预定义的大小70000
.有没有更好的方法可以分配我正在使用的大小而ByteBuffer
不是使用硬编码70000
?
还有什么比我正在做的更好的方法将我的标题和数据打包在一个字节数组中?我还需要确保它是线程安全的,因为它可以由多个线程调用.