我正在使用Java开发Android 2.3.3应用程序。
这个应用程序是一个iOS代码,无符号数据类型移植到Java。
在iOS上,它适用于UInt16
和UInt8
。在一个案例中,改为使用byte[]
我正在使用char[]
。
但我知道我必须使用DatagramPacket将char[]
作为byte[]
发送。
如果char []的一个元素是128,我该如何插入byte []并且接收器获得128.我不知道如果我这样做会发生什么:
char c = (char)128;
byte b = (byte)c;
哪个值为b
?
128 = 10000000. b = -1或b = 127?
如何在不丢失任何位的情况下将char[]
转换为byte[]
?
答案 0 :(得分:8)
在Java char
中是无符号的16位数。因此,您可以直接将uint16
转换为char
,而无需执行任何其他操作。
对于无符号8位数量,您有2个选项:
使用byte
。它还包含8位。你不会因为签名而丢失任何内容。但是,如果您使用它进行算术运算,则需要记住Java会自动将byte
扩展为int
并对其进行符号扩展。为了防止这种情况,总是像这样掩饰它:
字节b; int foo = 5 *(b& 0xFF);
使用char
。它是无符号的,可以保存16位,因此8位非常适合。要将byte
放入char
,请执行以下操作:
字节b; char c =(char)(b& 0xFF); //屏蔽低8位
将char
放入byte
只需执行:
char c;
byte b = (byte)c; // Truncates to 8 bits
请注意Java中的byte
已签名,因此每当您使用它进行算术运算时,您只需要屏蔽低8位(以防止符号扩展)。像这样:
byte b;
int foo = (b & 0xFF);
您可以使用字节执行所需的所有正常按位操作,而无需屏蔽:
byte b;
if (b & 0x80) ... // Test a flag
b |= 0x40; // Set a flag
b ^= 0x20; // Flip a flag from 0 to 1 or 1 to 0
b ^= ~0x10; // Clear a flag
byte x = b << 3; // Shift left 3 bits and assign
byte x = b >>> 4; // Shift right 4 bits and assign (WITHOUT sign extension)
答案 1 :(得分:2)
我认为您需要重新考虑您的方法,因此您最终无需将char[]
转换为byte[]
。
如果您的数据确实是字符,那么您希望查看各种序列化技术,例如使用new String(char[])
创建字符串,然后使用getBytes(Charset)
获取由给定{编码的字节{3}}(因为,当用ASCII或UTF-8或UTF-16等编码时,相同的字符会产生不同的字节。)
但是根据你的问题,听起来你并没有真正使用字符,你只是使用char
作为16位类型。如果是这样,那么进行转换并不困难,具体如下:
byte[] toBytes(char[] chars) {
byte[] bytes = new byte[chars.length * 2];
int ci, bi;
char ch;
bi = 0;
for (ci = 0; ci < chars.length; ++ci) {
ch = chars[ci];
bytes[bi++] = (byte)((ch & 0xFF00) >> 8);
bytes[bi++] = (byte)(ch & 0x00FF);
}
return bytes;
}
如果您希望结果是小端,请反转掩码。
但是,我会再看一下你的整体方法并尽量避免这种情况。