2011-10-01 60 views
89

Tôi muốn lưu trữ một số dữ liệu vào mảng byte trong Java. Về cơ bản chỉ là con số có thể mất đến 2 Byte cho mỗi số.Chuyển đổi mảng byte thành số nguyên trong Java và ngược lại

Tôi muốn biết cách tôi có thể chuyển đổi số nguyên thành mảng byte dài 2 byte và ngược lại. Tôi tìm thấy rất nhiều giải pháp googling nhưng hầu hết trong số họ không giải thích những gì xảy ra trong mã. Có rất nhiều công cụ chuyển dịch mà tôi không thực sự hiểu nên tôi sẽ đánh giá cao một lời giải thích cơ bản.

+3

bao nhiêu * làm * bạn hiểu về chút thay đổi? Nghe có vẻ như câu hỏi thực sự là "những gì bit chuyển dịch làm" nhiều hơn về việc chuyển đổi sang mảng byte, thực sự - nếu bạn thực sự muốn hiểu cách chuyển đổi sẽ hoạt động. –

+1

(Chỉ cần làm rõ, tôi ổn với một trong hai câu hỏi, nhưng nó có giá trị làm cho nó rõ ràng * mà * câu hỏi bạn thực sự muốn trả lời. Bạn có thể nhận được một câu trả lời đó là hữu ích hơn cho bạn theo cách đó.) –

+0

Được rồi tôi có quan điểm của bạn! Cảm ơn nhận xét. Tôi biết những gì thay đổi chút nào tôi chỉ không hiểu những gì nó được sử dụng để chuyển đổi mảng byte được nêu ra. – Chris

Trả lời

158

Sử dụng các lớp được tìm thấy trong không gian tên java.nio, cụ thể là ByteBuffer. Nó có thể làm tất cả công việc cho bạn.

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

Một thực hiện cơ bản sẽ là một cái gì đó như thế này:

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]); 
    } 
} 

Để hiểu được điều bạn có thể đọc bài viết WP này: http://en.wikipedia.org/wiki/Endianness

Các mã nguồn trên sẽ ra 34 12 78 56 bc 9a. 2 byte đầu tiên (34 12) đại diện cho số nguyên đầu tiên, vv Mã nguồn ở trên mã hóa số nguyên ở định dạng cuối nhỏ.

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); 
} 

Khi đóng gói byte ký vào một int, mỗi byte cần phải được che đậy bởi vì nó là đăng nhập mở rộng đến 32 bit (chứ không phải là zero-mở rộng) do sự cai trị khuyến mãi số học (được mô tả trong JLS, Chuyển đổi và Khuyến mãi).

Có một câu đố thú vị liên quan đến điều này được mô tả trong Java Puzzlers ("A Big Delight in Every Byte") của Joshua Bloch và Neal Gafter. Khi so sánh một giá trị byte đến một giá trị int, byte là đăng nhập mở rộng đến một int và sau đó giá trị này được so sánh với int

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

Lưu ý khác mà tất cả các loại số đăng nhập Java với ngoại lệ đối với char là một loại số nguyên không dấu 16 bit.

+3

Điều gì xảy ra nếu giá trị lớn hơn 127 ... – aProgrammer

+0

@Amit Không quan trọng. –

+0

Tôi nghĩ rằng '& 0xFF' là không cần thiết. –

30

Bạn cũng có thể sử dụng BigInteger cho các byte có độ dài thay đổi. Bạn có thể chuyển đổi nó thành dài, int hoặc ngắn, tùy theo nhu cầu của bạn.

new BigInteger(bytes).intValue(); 

hoặc để biểu thị cực:

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

Để có được byte lại chỉ:

new BigInteger(bytes).toByteArray() 
+0

Nó hữu ích cho tôi, cảm ơn – Jaycee

-3

tôi nghĩ rằng đây là một phương thức tốt nhất để đúc để int

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

byte chuyển đổi đầu tiên thành Chuỗi

comb=B+""; 

Bước tiếp theo là COMVERT đến một int

out= Integer.parseInt(comb); 

nhưng byte là trong cơn thịnh nộ của -128 đến 127 cho reasone này, tôi nghĩ là tốt hơn sử dụng rage 0 đến 255 và bạn chỉ cần làm này:

out=out+256; 
+0

Điều này là sai. Xem xét byte 0x01. Phương thức của bạn sẽ xuất ra 129 là sai. 0x01 nên xuất số nguyên 1. Bạn chỉ nên thêm 128 nếu số nguyên mà bạn nhận được từ parseInt là số âm. – disklosr

+0

Tôi có nghĩa là bạn nên thêm 256 không 128. Không thể chỉnh sửa sau đó. – disklosr

+0

đã thay đổi bài đăng để thêm 256 vì nó có thể hữu ích cho người khác! – 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; 
    } 
Các vấn đề liên quan