最近公司做的项目中有串口通讯,当然串口通讯的话底层我不管,上层应用的话就负责接收底层传过来的字节流了,接下来就是根据协议文档对字节流进行处理,上个项目中读取的温湿度传感器数据,协议上规定的是采集到的数据是ASCII数据,苦于java基础薄弱,对串口读取到的byte数据流不知道如何处理,虽然最后经过查阅资料弄出来了,但还是要对这些整理一番以加强理解。
大家都知道ASCII编码,这里解释一下,计算机中的数据存储和运算都使用的是二进制,我们常见的像a、b、c、1、2等等数字也好字符也好在计算机中都是以二进制的(0、1)的形式表示的,具体的哪些二进制数字表示哪个符号这就需要一套标准了,这也就诞生了ASCII这套编码标准。请看下面的ASCII表:
介绍完了ASCII,接下来看char,java里面称之为字符类型,可能大家会想到String,String是一个类,而char是像int、long、double等类型一样,String可以说成是char的字符集,我们可以给char赋值,例如:char c=112, char d = ‘a’,我们要知道这两种赋值的含义是不同的,那么不同在哪里呢,我们可以写一段代码测试下打印出的结果:
private static void test() { char c = 112; System.out.println(c); char d = 'a'; System.out.println(d); char e = 0x70; System.out.println(e); }
打印结果:
p
a
p
可能出乎大家的意料了,char类型,我们印象中一般都是单引号表示(PS:String类型双引号表示),而char类型一旦赋值了整数那么表示的就是ASCII了,大家对照ASCII表看看,十进制的112表示的正好是字符p,而0x70是用16进制表示的,表示的字符也是p。
byte表示一个字节,char表示字符例如一个汉字‘男’就表示一个字符,汉字可能占两个字节,也可能占多个字节,具体的要看编码,看下面的代码:
private static void testByte1() throws UnsupportedEncodingException { String string = "中国123"; byte [] bytes = string.getBytes("GB2312"); for (int i = 0 ; i< bytes.length ; i++){ System.out.print(bytes[i]); } }
打印结果:
中 国 1 2 3
-42-48 -71-6 49 50 51
byte和char之间可以互相转换,例如byte b = 112, 那么System.out.print((char)b)的结果就是字符p。
总结一下:char类型单引号表示就是一个字符,如果是整型就对应ASCII,byte表示字节,byte和char之间我们可以这样理解,byte无论用10进制还是16进制表示,如果对应ASCII表中能够找到对应的字符,那么经过char强转之后表示对应的字符,而char类型就是ASCII。
鉴于上面把byte、char、ASCII都总结了一下,这里说说java中的writeUTF和readUTF方法,只是简单的介绍下,先看代码:
private static void testUTF() { try { DataOutputStream dos = new DataOutputStream(new FileOutputStream( new File("K://test.txt"))); dos.writeUTF("png"); DataInputStream dis = new DataInputStream(new FileInputStream( new File("K://test.txt"))); byte[] data = new byte[dis.available()]; dis.read(data); for (byte b : data) { System.out.println(Integer.toHexString(b & 0xFF) + " "); } } catch (Exception e) { e.printStackTrace(); } }
打印结果:(16进制表示)
0
3
70
6e
67
writeUTF在写入数据流的时候会加上两个字节以表示字节的长度,0 3其实二进制就是0000 0011,表示后面有3个字节的长度,70 6e 67对应的ASCII就是png。