2011-09-28 99 views
3

我有一個Java類Java數據類型到字節數組

public class MsgLayout{ 
int field1; 
String field2; 
long field3; 
} 

我必須寫此對象在插座輸出流的字節數組。三個字段(實例變量)具有佈局。即field1必須佔用1個字節,field2必須佔用4個字節,而field3必須佔用8個字節。

ByteBuffer bbf = ByteBuffer.allocate(TOTAL_SIZE); 
bbf.put(Integer.toString(this.getField1()).getBytes(), 0, FIELD1_SIZE); 
bbf.position(FIELD2_OFFSET); 
bbf.put(Long.toString(this.getField2()).getBytes(), 0, FIELD2_SIZE); 
bbf.position(FIELD3_OFFSET); 
bbf.put(Long.toString(this.getField3()).getBytes(), 0, FIELD3_SIZE); 
byte[] msg = bbf.array(); 

使用上面的代碼,我試圖根據其所需的大小來適應字節數組中的每個字段。但我得到IndexOutOfBoundException 總之,問題是如何適應佈局定義大小的字段。例如FIELD1_OFFSET = 0, FIELD1_SIZE=1, FIELD2_OFFSET=1, FIELD2_SIZE=4, FIELD3_OFFSET=5, FIELD3_SIZE=8. 現在,當我將field1轉換爲字符串時,轉換爲byte []時不適合1字節。如果我不轉換爲字符串,並使用putInt(int)它將4個字節寫入結果字節數組。

+0

除非您可以保證字段的範圍,否則嘗試將它們存儲到緩衝區中過小的固定大小插槽時將丟失數據。你打算如何解決這個問題? – kdgregory

+0

你是什麼意思的範圍?我不能在一個字節中插入Integer嗎?我不能以4字節存儲字符串嗎? –

+0

@ hoshang.varshney,Java中沒有int是4個字節,String是可變長度。當你說字符串是你想到一個字符,即一個字符?在Java中,由於使用unicode,所以單個字符佔用2個字節。 –

回答

0

field1可僅具有一個字節的數據,但它的字符串表示將一個或多個字符(例如"0""63""127")。字符串中的每個字符實際上都是一個char(兩個字節的值)。所以我希望一個字節的數據在通過字節 - >字符串 - >字節[]轉換時可以膨脹到2到6個字節的數據。

2

你的代碼當前正在做的是將數字字段編碼爲字符串,然後輸出這些字符的字節。

我會建議使用的是DataOutputStream類來包裝你的SocketOutput流和寫你的二進制數據,像這樣:

DataOutput output = new DataOutputStream(socketOutputStream); 

int field1 = 1; 
String field2 = "Hello"; 
long field3 = 5000000000L; 

output.writeByte(field1); 
output.writeBytes(field2.substring(0, 3)); 
output.writeLong(field3); 

有此代碼一對夫婦的假設。首先,我假設字段2需要4個字符,每個字符串行化爲一個字節。如果你想使用類似UTF-8的任何多字節編碼,那麼你需要做一些不同的事情。其次,我假設字段2將始終具有至少4個字符。