2013-10-01 30 views
0

我需要使用Java代碼將Byte Array值寫入Cassandra。然後,我將讓我的C++程序讀取與Cassandra相同的Byte Array數據。Big Endian或Small Endian將數據存儲到Cassandra中?

即字節數組是由三個字節數組如下所述 -

short schemaId = 32767; 
long lastModifiedDate = "1379811105109L"; 
byte[] avroBinaryValue = os.toByteArray(); 

現在,我將寫schemaIdlastModifiedDateavroBinaryValue在一起成爲單個Byte Array和所得字節數組,我將回寫成卡桑德拉然後我將具有我的C++程序,其將檢索卡桑德拉該字節數組數據,然後將反序列化以提取schemaId,從它lastModifiedDateavroBinaryValue

所以現在我很迷惑我是否應該在這裏使用大端在我的Java代碼,而寫卡桑德拉?或者在將數據存儲到Cassandra時使用小端字節順序?

下面是代碼,我至今在Java中,將序列一切都變成單字節數組了......

public static void main(String[] args) throws Exception { 

    String os = "whatever os is"; 
    byte[] avroBinaryValue = os.getBytes(); 

    long lastModifiedDate = 1379811105109L; 
    short schemaId = 32767; 

    ByteArrayOutputStream byteOsTest = new ByteArrayOutputStream(); 
    DataOutputStream outTest = new DataOutputStream(byteOsTest); 

    outTest.writeShort(schemaId); // first write schemaId 
    outTest.writeLong(lastModifiedDate); // second lastModifiedDate 
    outTest.writeInt(avroBinaryValue.length); // then attributeLength 
    outTest.write(avroBinaryValue); // then its value 

    byte[] allWrittenBytesTest = byteOsTest.toByteArray(); 

    // write this allWrittenBytesTest into Cassandra 

    // now deserialize it and extract everything from it 
    DataInputStream inTest = new DataInputStream(new ByteArrayInputStream(allWrittenBytesTest)); 

    short schemaIdTest = inTest.readShort(); 

    long lastModifiedDateTest = inTest.readLong(); 

    int sizeAvroTest = inTest.readInt(); 
    byte[] avroBinaryValue1 = new byte[sizeAvroTest]; 
    inTest.read(avroBinaryValue1, 0, sizeAvroTest); 


    System.out.println(schemaIdTest); 
    System.out.println(lastModifiedDateTest); 
    System.out.println(new String(avroBinaryValue1)); 

} 

而且我也想看看是否有任何有效的或正確的方法因爲我需要使用C++程序從Cassandra中檢索這些數據,所以我不想在C++端有任何問題。所以我試圖確定何時將這些數據寫入到Cassandra中Java方面,一切都看起來很不錯..

現在,爲了測試我所做的一切是 - 我在寫這個字節數組轉換爲從Java程序中的一個文件d我讀使用相同的文件C++程序,然後相應地反序列化字節數組..

我希望我的問題是不夠清楚..誰能幫助我?

+0

你知道[字節緩衝區(HTTP:/ /docs.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html)將允許你直接指定或大或小尾數,那麼所有你需要是確保您在C++的側正確解碼嗎? [見這個問題](http://stackoverflow.com/questions/5625573/byte-array-to-short-array-and-back-again-in-java)爲一個類似的,但不完全相同的例子。 – WhozCraig

+0

@WhozCraig:感謝您的建議。我不知道ØByteBuffer的所有..我只是通過它去。它看起來像我可以讓我的Java程序使用的ByteBuffer而寫入卡桑德拉更好?對?然後,我可以使用C++程序來指定我需要在C++端遵循哪一個endian。是否有可能讓我在上面的Java解決方案上給出一個示例基礎,瞭解如何使用ByteBuffer完成同樣的任務?這對我有很大的幫助..謝謝.. – AKIWEB

+0

在我的評論中的鏈接問題有一個相當不錯的樣本,如何做一個'短'。你應該可以用32位或64位的int或long來做同樣的事情。 「知道」字節流中的值是big-endian或little endian(我個人更喜歡前者),這大大簡化了C++代碼,並且在重新組裝一個代碼中有很多例子,或者你可以使用'ntohl ()'。 – WhozCraig

回答

0

爲什麼不使用serailization framwework像谷歌的protobuf(http://code.google.com/p/protobuf/)這種方式,你不必擔心底層的細節,讀,寫任何語言和工具回來

+0

由於某種原因,我不能使用它,因爲我不想序列化兩次,因爲我的實際值是Avro二進制編碼值...並且我也不要求評估不同的序列化框架。 – AKIWEB

+0

就我所知,做更好的方法將是一個序列化框架。既然它在這裏沒有問題,除非你正在存儲和讀取相同的字節數,否則它並不重要。如果你要從不同的字節數機器讀取值,那麼使用最常見的值,這樣轉換次數就會減少。 – Pradheep

+1

是的,我同意Pradheep ..但我的實際價值是Avro二進制編碼值本身是一個數據序列化格式..我不能二進制編碼數據再次與其他一些序列化格式..因爲我需要合併三個字節陣列到一起一個...如果我使用另一種序列化格式,那麼我需要序列化/解除分裂兩次,這不是我正在尋找的內容。 – AKIWEB