对JAVA中char、ASCII、byte、writeUTF、readUTF的认识

最近公司做的项目中有串口通讯,当然串口通讯的话底层我不管,上层应用的话就负责接收底层传过来的字节流了,接下来就是根据协议文档对字节流进行处理,上个项目中读取的温湿度传感器数据,协议上规定的是采集到的数据是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。