2017-01-09 65 views
0

我有一個方法,使一個字節數組按照以下格式。如何獲得我用來製作大字節數組的實際字節?

  • 首先它得到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? 

有沒有辦法把它找回來?

+0

用兩種方法拆分你的方法:一個生成並返回avroBytes,第二個將它們作爲參數生成bytesToStore。 –

+0

在我的情況下,在程序結束時,一旦我有'bytesToStore',那麼我需要返回我的avroBytes進行一些調試。這只是一次練習,所以這就是爲什麼我想做一些驗證。 – john

+0

總是有'Arrays.copyOfRange(bytesToStore,2 + 8 + 4,bytesToStore.length)'。但我懷疑你最好返回ByteBuffer而不是字節數組。 – VGR

回答

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接口,可能有方法可直接從序列化的字節解壓縮數據,而無需進行中間複製。

+0

是的,我測試了基於VGR的建議,它工作得很好。 – john

+0

你能幫助我的另一個[問題](http://stackoverflow.com/questions/41947887/deserialize-array-in-a-particular-format-to-get-map-from-it)我的也是在字節數組和字節緩衝區? – john

0

從代碼,它看起來像已經存在是返回avroBytes的方法,如:

byte[] avroBytes = getAvroBytes(holderMap, record);

這種方法需要holderMaprecord爲aguments,並期待在那裏serialize被調用的代碼,你已經有了這兩個值。因此,如果可能的話,您可以在致電serialize之前致電getAvroBytes,並將其作爲參數傳遞給serialize方法。

相關問題