Java串口通信:从十六进制字符串到字节数组的正确转换与发送

文章讲述了在Java中处理十六进制字符串转字节数组的常见问题,包括错误地将十六进制视为ASCII值、处理带空格的字符串、字节溢出以及Java中无符号类型的缺失,提供了正确的转换方法和示例。
摘要由CSDN通过智能技术生成

场景:错误的处理方式将十六进制字符串视为普通文本,导致输出的是字符的ASCII值而非原始字节。正确的方法则是将每个十六进制字符对转换为对应的字节值。

1. 十六进制字符串与字节数组的关系

在串口通信中,数据通常以字节形式传输。为了方便阅读和编写,这些字节值会被编码为十六进制字符串。

2. 错误的处理方式与问题

字节序列“53 A8 C0 00 00 20 41 00…”代表一组待发送的字节数据。在实际编程中会遇到两种错误:

错误一:直接调用 getBytes() 方法

String hexString = "53 A8 C0 00 00 20 41 00...";
byte[] data = hexString.getBytes();

因为Java的 getBytes() 方法不会直接接受十六进制字符串作为输入并将其转换为字节数组,而是将十六进制字符串视作普通文本,将每个字符转换为其对应的ASCII值,而非字节值。输出结果与预期不符。

错误二:未正确处理带空格的十六进制字符串

String hexString = "53 A8 C0 00 00 20 41 00...";
byte[] data = hexString.replaceAll("\\s", "").getBytes(StandardCharsets.UTF_8);

虽然去除了空格,但使用 getBytes() 方法依然会将字符转换为ASCII值,UTF-8编码可能导致非预期的字节序列。

3. 正确的十六进制字符串转字节数组方法

private static byte[] hexStringToByteArray(String s) {
    String[] hexParts = s.split(" ");
    byte[] data = new byte[hexParts.length];

    for (int i = 0; i < hexParts.length; i++) {
        data[i] = (byte) Integer.parseInt(hexParts[i], 16);
    }

    return data;
}

使用 split(" ") 将十六进制字符串按照空格分割成多个部分,然后逐个将每个部分转换为字节并放入数组中。

4.Java中字节溢出问题

Java中的byte类型是有符号的,值域范围为-128到127。当处理十六进制数值时,如果该数值对应的十进制值超过127,转换为byte类型时会触发字节溢出,导致结果以负数形式呈现。

举例说明:十六进制A8转为十进制

以十六进制数A8为例,对应的十进制数168,但Java处理有符号的8位字节(即byte类型)时会发生变化。

  1. 十六进制转二进制A8对应的二进制形式为10101000

  2. 识别符号位:在8位带符号整数中,最高位(最左边的位)为符号位。对于10101000,最高位为1,表明这是一个负数。

  3. 计算负数绝对值:对于负数,其补码表示方法为:取反加一得到原码的补码。A8的补码为01010111,转换为十进制为87

  4. 得出最终负数:根据补码计算规则,负数的值等于-(-87 + 1),即-88。因此,在8位有符号整数的表示下,十六进制数A8对应着十进制的-88

5.Java不支持无符号类型

Java不像C或C++那样提供直接的无符号整数类型,如unsigned char。所有的基本整数类型(如byteshortintlong)都是有符号的,要实现无符号效果,需要通过byte模拟转换为int类型处理,

byte signedByte = (byte) 0xA8; // 假设为从串口接收到的有符号字节数据
int unsignedInt = signedByte & 0xFF; // 通过位运算将字节转换为无符号整数

System.out.println(unsignedInt); // 输出:168

使用位与操作符(&)与常量0xFF(二进制全1,相当于十进制的255)进行位运算。由于byte只有8位,其余高位均为0,与0xFF进行位与运算相当于保留其原有的8位二进制值,同时将高位补足为0,从而得到一个无符号的int值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yeats_Liao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值