十、IO流--编码和解码

十、IO流–编码和解码

程序写入“abc”到硬盘上,首先将“abc”在码表中找到对应的字符,获取字符对应的二进制数据。然后将二进制数据保存到硬盘上。
程序读取文件,首先读取文件中的二进制数据,然后将二进制数据根据码表中的数据找到对应的字符,返回给程序进行展示。
编码:将看得懂的字符变成看不懂的码值,这个过程我们称之为编码。【字符转为码值】
解码:将看不懂的码值转成我们看得懂的字符,这个过程我们称之为解码。【码值转为字符】

在这里插入图片描述

码表

ASCII码表: 美国标准信息交换码表。用一个字节的7位可以表示。【(-128-+127),256个数字,但是美国人并没使用完,所以只使用了一个字节的7位表示】–单字节马鞭
IOS8859-1: ASCII码表包含的仅仅是英文字母,并没有完全占满256个编码位置。所以它以ASCII为基础,加入了192字母已经字符。因而它依然是一个单字节编码,只是比ASCII更全面。【将256个码值,全都占满。唯一一个占满码值的码表。】

GB2313 : 英文占一个字节,中文占两个字节。
GBK : 以GB2312为基础,加入个少数民族的文字。

Unicode:每个国家都有每个国家的码表。所以有人写出了一个规范,这个规范要求,如果有人实现了Unicode规范,那么你就会容纳世界所有的文字。【更偏向于是一种规范。而不是一种码表】【使用unicode进行编码时,实际上使用的是utf-16】

UTF-8: UTF-8实现了Unicode规范。英文占一个字节,中文占三个字节。

UTF-16:英文、中文都占两个字节、。

编码解码常用方法
str.getBytes() 按照平台默认的编码集进行编码。
str。getBytes(CharSet) 指定编码集进行编码。

new String(byte[]buf) 按照平台默认的编码集进行解码
new String(byte[]buf ,CharSet) 指定编码集进行编码

public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		
	     String str="中国";
	     byte[] bytes = str.getBytes("gbk");
	     System.out.println("编码后的码值:"+Arrays.toString(bytes));		 
		 
	     String str2=new String(bytes,"gbk");
	     System.out.println(str2);
	     
	}

unicode
使用unicode编码和解码时,实际上都是用的是utf-16进行编码的。【英文、中文都占两个字节】
utf-16编码时,前两位都为 【-2,-1】 。 一个代表标志位。傻逼做法。

代码

public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		
	     String str="aa中国";
	     byte[] bytes = str.getBytes("utf-16");
	     System.out.println("utf-16 编码后的码值:"+Arrays.toString(bytes));		 
		 
	     String str2="aa中国";
	     byte[] bytes2 = str2.getBytes("unicode");
	     System.out.println("unicode 编码后的码值:"+Arrays.toString(bytes2));		 
		 
	     
	}

控制台:

utf-16 编码后的码值:[-2, -1, 0, 97, 0, 97, 78, 45, 86, -3]
unicode 编码后的码值:[-2, -1, 0, 97, 0, 97, 78, 45, 86, -3]

乱码还原

大家好—使用GBK进行编码,然后用ISO8859-1进行解码,此时被解码成?ó??? 。这个字符串不是解码后真正的符号,而是由于eclispe控制台不识别特殊的符号导致。此时,可以进行debug,看到真正解码后的符号、

public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		
	  
	     String  str="大家好";
	     byte[] bytes = str.getBytes();//采用平台编码集进行编码GBK
	  	 System.out.println("编码的码值:"+Arrays.toString(bytes));

	  	 str=new String(bytes,"iso-8859-1");
	  	 System.out.println(str);
	}

控制台:

编码的码值:[-76, -13, -68, -46, -70, -61]
?ó????

Debug模式,获取真正解码后的符号 ´ó¼ÒºÃ
在这里插入图片描述

由于前后编码集不一致,导致乱码,这时候再根据乱码进行还原。

public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		
	  
	     String  str="´ó¼ÒºÃ";
	     byte[] bytes = str.getBytes("iso-8859-1");
	  	 System.out.println("编码的码值:"+Arrays.toString(bytes));

	  	 str=new String(bytes,"gbk");
	  	 System.out.println(str);
	}

总结:并不是所有的乱码都可以被还原。字符串根据码表A进行编码时获取码值,然后码值在通过码表B进行解码,如果码值在码表中都存在,即使乱码,也可以被还原。但是如果码值在码表中不存在,则数据丢失。出现乱码也不能被还原。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值