use*_*644 1 java arrays binary serial-port bytearray
我必须做以下事情
在包含4个字节的char数组的末尾以十六进制追加2个字节,因此结果为6个字节.
将上面的6字节字节数组转换为char数组,将其传递给函数crcresult.(该函数只接受char数组).
最后在6字节的末尾合并crc 2字节.
我已在单独的java类中测试了以下程序,并且它有效.
public class CharBytetest
{
public static void main(String[] args)
{
char charbuffer1[] = {0x01,0x05,0x00,0x03};
byte[] bufferbyte1 = new String(charbuffer1).getBytes();// converts chararray to byte array
byte byte4 = (byte)0xFF;
byte byte5 = (byte)0x00;
byte[] bufferbytemerge1 = new byte[bufferbyte1.length+2];
System.arraycopy(bufferbyte1, 0, bufferbytemerge1, 0, bufferbyte1.length);
bufferbytemerge1[bufferbyte1.length]= byte4;
bufferbytemerge1[bufferbyte1.length +1 ]= byte5;
//bufferbytemerge1 contains 6 byte (charbuffer1 + byte4 + byte5 )
String str = new String(bufferbytemerge1);
//bufferbytemerge1 converted to char array
char[] charbuffer2 = str.toCharArray();
byte[] bufferbyte2 = new String(charbuffer2).getBytes();
int crcresult;
//char array sent to crc function
crcresult = CalculateCRC.CRC16(charbuffer2,6);
byte byte1 = (byte)((crcresult >> 8) & 0xFF); // first 8 bits of last 16 bits
byte byte0 = (byte)(crcresult & 0xFF); // last 8 bits
byte[] bufferbytemerge2 = new byte[bufferbyte2.length + 2];
System.arraycopy(bufferbyte2, 0, bufferbytemerge2, 0, bufferbyte2.length);// copy original data stored in bytebuffer
bufferbytemerge2[bufferbyte2.length] = byte1; // append crc16 byte 1
bufferbytemerge2[bufferbyte2.length + 1] = byte0; // append crc16 byte 2
//bufferbytemerge2 contains total 8 bytes
for (byte b : bufferbytemerge2){
System.out.format("0X%x ", b);
}
}
}
Run Code Online (Sandbox Code Playgroud)
看到的输出是
0X1 0X5 0X0 0X3 0Xff 0X0 0X7c 0X3a
Run Code Online (Sandbox Code Playgroud)
但是我的问题当我实现上面的东西在串口发送"bufferbytemerge2"特别是modbus时,转换错误被视为
java.lang.ArraIndexOutOfBoundsException : 65454
at com.wexsnet.wesModbus.comm.req.CalculateCRC.crc16 <CalculateCRC.java:59>
Run Code Online (Sandbox Code Playgroud)
我试图分析在每一步获得的字节,似乎问题出现在第二步.即,当bufferbytemerge1转换为char数组时.
根据上面的代码,"bufferbyte2"应该包含01 05 00 03 FF 00但是当我尝试发送"bufferbyte2"时它发送01 05 00 03 ef bf bf 00
这是因为"bufferbytemerge1"字节数组到char数组"charbuffer2"的转换是不正确的.或者将"charbuffer2"char数组转换为字节数组"bufferbyte2"是不正确的.请帮助我们如何正确转换它.
不要用于char在Java中保存字节值.我意识到这是C中的标准做法,但在Java中,字节byte只属于数组.
每次将字节转换为字符串或将字符串转换为字节时,您使用的是编码器或解码器Charset.在许多Charsets(包括你的系统显然使用的UTF-8)中,并非每个字节值都可以转换为字符; 这些字节将被丢弃或替换为某个默认号码.在许多字符集中,某些字符不对应于单个字节,而是对应于多个字节,这是您ef bf bf来自的地方.
这就是您使用new String(byte[])和String.getByes()破坏数据的原因.
不要使用char数组.不要将字节转换为字符串或从字符串转换.仅使用byte数组来保存字节.
如果要将byte数组转换为16位值的数组,请使用ByteBuffer将其转换为short数组:
short[] sixteenBitValues = new short[byteArray.length / 2];
ByteBuffer.wrap(byteArray).asShortBuffer().get(sixteenBitValues);
Run Code Online (Sandbox Code Playgroud)
通常,如果要将字节附加到字节数组,则应使用ByteBuffer:
ByteBuffer buffer = ByteBuffer.allocate(oldByteArray.length + 2);
buffer.put(oldByteArray);
buffer.asShortBuffer().put(crcresult);
byte[] newByteArray = buffer.array();
Run Code Online (Sandbox Code Playgroud)
如果您的CRC16方法仅对char数组进行操作,则需要避免使用String或任何其他将调用Charset编码的方法,并自行强制使用字节char值:
char[] charBuffer2 = new char[byteBuffer.length];
for (int i = 0; i < byteBuffer.length; i++) {
charBuffer2[i] = (char) (byteBuffer[i] & 0xff);
}
Run Code Online (Sandbox Code Playgroud)
听起来你的CRC16方法正在使基于C的假设char保持一个字节,所以如果你对该类有任何控制,你应该改变它以接受一个byte[]参数.