1

我正在用 Java 开发一个 Android 2.3.3 应用程序。

这个应用程序是一个带有未签名数据类型端口到 Java 的 iOS 代码。

在 iOS 上,它与UInt16和一起使用UInt8。在一种情况下,byte[]我使用的是char[].

但是知道我必须char[]使用DatagramPacketbyte[]发送它。

如果 char[] 的一个元素是 128,我该怎么做才能插入到 byte[] 并且接收器得到 128。我不知道如果我这样做会发生什么:

char c = (char)128;
byte b = (byte)c;

哪个会b有价值?
128 = 10000000。b = -1 还是 b = 127?

如何在不丢失任何char[]的情况下转换为?byte[]

4

2 回答 2

8

在 Javachar中是一个无符号的 16 位量。因此,您可以直接将您的转换uint16为,char而无需执行任何其他操作。

对于无符号 8 位数量,您有 2 个选项:

  1. 使用byte. 它还拥有 8 位。您不会因为已签名而丢失任何位。但是,如果您使用它进行算术运算,您需要记住 Java 会byte自动扩展为 anint并对其进行符号扩展。为了防止这种情况总是像这样掩盖它:

    字节 b; int foo = 5 * (b & 0xFF);

  2. 使用char. 它是无符号的,可以保存 16 位,因此 8 位将非常适合其中。要将 abyte放入 a 中char,只需执行以下操作:

    字节 b; 字符 c = (char)(b & 0xFF); // 屏蔽掉低8位

将 achar放入bytejust 中:

char c;
byte b = (byte)c; // Truncates to 8 bits

请注意,byte在 Java 中是有符号的,因此无论何时使用它进行算术运算,都只需要屏蔽低 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)
于 2012-07-17T17:22:14.500 回答
2

我认为您需要重新考虑您的方法,这样您最终就不需要转换char[]byte[].

如果您的数据确实是字符,那么您需要查看各种序列化技术,例如使用new String(char[])来创建一个字符串,然后使用getBytes(Charset)来获取由给定编码的字节Charset(因为,当然,相同的字符会导致不同的字节时以 ASCII 或 UTF-8 或 UTF-16 等编码)。

但从你的问题来看,听起来你并没有真正使用字符,你只是在使用char16 位类型。如果是这样,进行转换并不困难,大致如下:

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

如果您希望结果为小端,请反转掩码。

但同样,我会看看你的整体方法并尽量避免这种情况。

于 2012-07-17T14:56:02.327 回答