2011-10-01 92 views
89

我想將一些數據存儲到Java中的字節數組中。基本上只需要每個數字最多2字節的數字。將字節數組轉換爲Java中的整數,反之亦然

我想知道我怎麼能一個整數轉換成2字節長的字節數組,反之亦然。我發現很多解決方案使用谷歌搜索,但其中大多數都沒有解釋代碼中會發生什麼。有很多變化的東西,我真的不明白,所以我會欣賞一個基本的解釋。

+3

多少*做*你瞭解了位移位?聽起來這個問題真的是「什麼是位移」,而不是轉換爲字節數組,實際上 - 如果你真的想了解轉換的工作方式。 –

+1

(只是爲了澄清,我對任何一個問題都沒有問題,但值得說清楚*你真的想回答哪個問題?你可能會得到一個對你更有用的答案。) –

+0

好吧,我明白了你的觀點!謝謝你的評論。我知道什麼位移,我只是不明白它用於轉換字節數組。 – Chris

回答

158

使用ByteBufferjava.nio命名空間中的類,特別是。它可以爲你做所有的工作。

byte[] arr = { 0x00, 0x01 }; 
ByteBuffer wrapped = ByteBuffer.wrap(arr); // big-endian by default 
short num = wrapped.getShort(); // 1 

ByteBuffer dbuf = ByteBuffer.allocate(2); 
dbuf.putShort(num); 
byte[] bytes = dbuf.array(); // { 0, 1 } 
4

基本實現將是這樣的:

public class Test { 
    public static void main(String[] args) { 
     int[] input = new int[] { 0x1234, 0x5678, 0x9abc }; 
     byte[] output = new byte[input.length * 2]; 

     for (int i = 0, j = 0; i < input.length; i++, j+=2) { 
      output[j] = (byte)(input[i] & 0xff); 
      output[j+1] = (byte)((input[i] >> 8) & 0xff); 
     } 

     for (int i = 0; i < output.length; i++) 
      System.out.format("%02x\n",output[i]); 
    } 
} 

爲了瞭解事情你可以看到這篇文章WP:http://en.wikipedia.org/wiki/Endianness

上面的源代碼將輸出34 12 78 56 bc 9a。前2個字節(34 12)表示第一個整數等。上述源代碼以little endian格式編碼整數。

92
byte[] toByteArray(int value) { 
    return ByteBuffer.allocate(4).putInt(value).array(); 
} 

byte[] toByteArray(int value) { 
    return new byte[] { 
     (byte)(value >> 24), 
     (byte)(value >> 16), 
     (byte)(value >> 8), 
     (byte)value }; 
} 

int fromByteArray(byte[] bytes) { 
    return ByteBuffer.wrap(bytes).getInt(); 
} 
// packing an array of 4 bytes to an int, big endian 
int fromByteArray(byte[] bytes) { 
    return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF); 
} 

當包裝符號字節爲一個int,每個字節需要被屏蔽掉,因爲它是符號擴展到32位(而不是零擴展)由於算術提升規則(描述於JLS,轉換和促銷)。

有一個有趣的與此相關的Java中描述的謎題由Joshua Bloch和尼爾Gafter拼圖(「A大喜悅中的每個字節」)。當比較一個字節值int值,字節符號擴展爲int,然後該值與其他INT

byte[] bytes = (…) 
if (bytes[0] == 0xFF) { 
    // dead code, bytes[0] is in the range [-128,127] and thus never equal to 255 
} 

注意,所有數值類型在Java中,出現異常燒焦簽字一個16位無符號整數類型。

+3

如果值大於127 ... – aProgrammer

+0

@Amit無關緊要。 –

+0

我認爲'&0xFF'是不必要的。 –

30

您還可以使用BigInteger獲取可變長度字節。您可以將其轉換爲long,int或short,以適合您的需求。

new BigInteger(bytes).intValue(); 

或表示極性:

new BigInteger(1, bytes).intValue(); 

要獲得字節回到剛:

new BigInteger(bytes).toByteArray() 
+0

這對我很有用,謝謝 – Jaycee

-3

我認爲這是一個最好的方式來強制轉換爲int

public int ByteToint(Byte B){ 
     String comb; 
     int out=0; 
     comb=B+""; 
     salida= Integer.parseInt(comb); 
     out=out+128; 
     return out; 
    } 

首先將字節轉換爲字符串

comb=B+""; 

下一步comvert到INT

out= Integer.parseInt(comb); 

但字節在-128到127風靡一時這個reasone,我認爲這是更好地利用憤怒0到255,你只需要做這樣的:

out=out+256; 
+0

這是錯誤的。考慮字節0x01。你的方法會輸出129,這是錯誤的。 0x01應輸出整數1.如果從parseInt獲得的整數爲負數,則只應添加128。 – disklosr

+0

我的意思是你應該添加256而不是128.之後無法編輯它。 – disklosr

+0

更改後添加256,因爲它可能對別人有用! – apmartin1991

1
/** length should be less than 4 (for int) **/ 
public long byteToInt(byte[] bytes, int length) { 
     int val = 0; 
     if(length>4) throw new RuntimeException("Too big to fit in int"); 
     for (int i = 0; i < length; i++) { 
      val=val<<8; 
      val=val|(bytes[i] & 0xFF); 
     } 
     return val; 
    } 
相關問題