所以,我在尝试使读卡器在多功能打印机上正常工作时遇到了一些麻烦,我将问题缩小到字节[]传递为字符串时字符串输出的奇怪值构造函数参数。我无法通过MFP调试应用程序,并且日志工具根本无法与读卡应用程序一起工作(这是嵌入式编程世界,伙计们!),所以我的工作调试工作几乎都基于打印屏幕上的值有时候并不像你想的那样。
好的,我们走了:当我在读卡器上“刷卡”时,我的Java程序会收到一个字节[]。现在,有两种方法可以显示它:
//Supposing that bytes is the byte[] received
BigInteger bi = new BigInteger(bytes); bi.toString(16); //I think it works fine
String str = new String(bytes); //Suggested by the developer; sucks
确定。第一个输出“3538353536”。有点奇怪的十六进制值,但它实际上是正确的值;自从我做了一个测试:
byte[] bytes = {0x35, 0x38, 0x35, 0x35, 0x36};
BigInteger bi = new BigInteger(bytes);
System.out.println(bi.toString(16));
考虑到它返回相同的值(3538353536),我将把它作为实际的byte []值。现在,当我尝试第二种方式时:
new String(bytes);
在这种情况下,我的返回值是58556.更糟糕的是,每次事情都不那么开心,就像传递一样的论据
{(byte)9F, (byte)0xA8, (byte)0xEE};
将输出[tab - 真的是一个标签,而不是写标签]¨î
我在一些地方读过新的String(字节)是正确的方法,更是如此,它是读卡器开发人员的例子。但它不起作用。在我开始质疑开发人员之前,我想知道这个输出与bi.toString(16)的比较,这似乎是正确的方法。
对于关于一个可以用两行总结的问题的相当长篇的帖子感到抱歉,但我想让一切都变得清晰,以便直接,快速地回答。
编辑:感谢大家的投入,我明白了。现在我很困惑我是否应该考虑ASCII值(58556)或十六进制(“0x3538353536”) - 也就是说,如果它实际上应该被解释为十六进制 - 但这是一个我将带给开发人员的问题。
答案 0 :(得分:4)
正如javadoc所说,String(bytes)
“通过使用平台的默认字符集解码指定的字节数组来构造一个新的字符串”。
所以正在发生的事情是它将数据解释为以字节格式存储的字符。如果你查找一个ASCII图表,你会看到0x35 ='5'等等。
另一方面,ToString将数据转换为字符串表示,正如您所期望的那样。
答案 1 :(得分:2)
转换为十进制数时,原始字节数组{0x35, 0x38, 0x35, 0x35, 0x36}
为:{53, 56, 53, 53, 54}
如果使用ASCII值转换将变为{'5', '8', '5', '5', '6'}
,因此您使用默认字符集获取字符串58556
你的平台。
BigInteger构造函数 NOT 与String构造函数相同。根据Javadoc:
public BigInteger(byte[] val)
将包含BigInteger的二进制补码二进制表示的字节数组转换为BigInteger。假设输入数组采用big-endian字节顺序:最重要的字节位于第0个元素中。