我有一个方法,按照以下格式制作一个字节数组。
以下是方法:
public static byte[] serialize(final Record record, final int clientId,
final Map<String, String> holderMap) throws IOException {
byte[] avroBytes = getAvroBytes(holderMap, record);
byte[] snappyCompressed = Snappy.compress(avroBytes);
int size = (2+8+4) + snappyCompressed.length;
ByteBuffer buffer = ByteBuffer.allocate(size);
buffer.order(ByteOrder.BIG_ENDIAN);
buffer.putShort((short) clientId);
buffer.putLong(System.currentTimeMillis());
buffer.putInt(snappyCompressed.length);
buffer.put(snappyCompressed);
buffer.rewind();
byte[] bytesToStore = new byte[size];
buffer.get(bytesToStore);
return bytesToStore;
}
现在,我希望在avroBytes
bytesToStore
byte[] bytesToStore = serialize(......);
// now how can I get actual `avroBytes` using bytesToStore?
有没有办法让它回来?
答案 0 :(得分:1)
根据代码,压缩版本从bytesToStore[14]
开始,因此一种简单但不一定最有效的方法是从该位置复制字节,并调用Snappy.uncompress(bytes)
。
这样的事情:
public static int HEADER_SIZE = 2 + 8 + 4;
public static byte[] extractAvroBytes(byte[] bytesToStore) throws IOException {
byte[] bytes = Arrays.copyOfRange(bytesToStore, HEADER_SIZE, bytesToStore.length);
return Snappy.uncompress(bytes);
}
我还没有对此进行测试,因此可能需要进行一些调整。
根据您使用的snappy的Java接口,可能有一些方法可以直接从序列化字节解压缩数据,而无需制作中间副本。
答案 1 :(得分:0)
从代码中看,已经有一个返回avroBytes
的方法,例如:
byte[] avroBytes = getAvroBytes(holderMap, record);
此方法需要holderMap
和record
作为aguments,并且查看调用serialize
的代码,您已经拥有这两个值。因此,如果可能,您可以在调用getAvroBytes
之前调用serialize
并将其作为参数传递给serialize
方法。