如何获得用于制作大字节数组的实际字节数?

时间:2017-01-09 22:32:30

标签: java arrays bytebuffer

我有一个方法,按照以下格式制作一个字节数组。

  • 首先它获得了avroBytes。
  • 然后它快速压缩它。
  • 然后它生成另一个具有特定格式的字节数组,如下所示。

以下是方法:

  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?

有没有办法让它回来?

2 个答案:

答案 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);

此方法需要holderMaprecord作为aguments,并且查看调用serialize的代码,您已经拥有这两个值。因此,如果可能,您可以在调用getAvroBytes之前调用serialize并将其作为参数传递给serialize方法。