【Java文件流】简单明了的“编码”教程

本文深入浅出地讲解了编码与解码的概念,探讨了不同码表如ASCII、ISO8859-1、GB2312、GBK、Big5、Unicode、UTF-8和UTF-16的特点及应用。通过Java示例代码,演示了如何进行编码与解码操作,揭示了乱码产生的原因及解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很多人说,编码与解码太迷了,根本不知道它是在编码什么,在解码什么。或许这时,你应该尝试一下我这篇文章。


从源头来说,还是因为计算机和人的根本区别,计算机看的是二进制机器码,而我们只能看懂特殊字符(英文,中文),把特殊字符变成二进制码的过程就成为 编码。又由于地球上存在很多种类的语言,每种语言的每个元素都是一个字符(例如中文“你”,“好”),把中文字符变成二进制机器码,这个过程就称为 有一定格式的编码,或者叫 编码方式

  • 编码: 把看得懂的字符变成看不懂码值这个过程我们称作为编码。
  • 解码: 把码值查找对应的字符,我们把这个过程称作为解码。
  • 注意: 以后编码与解码一般我们都使用统一的码表(码表,即编码方式)。否则非常容易出乱码。

码表

欧美地区常用编码:

  • ASCII:美国标准信息交换码。用一个字节表示。
  • ISO8859-1:拉丁码表。欧洲码表,用一个字节的8位表示。又称Latin-1(拉丁编码)或“西欧语言”。ASCII码是包含的仅仅是英文字母,并且没有完全占满256个编码位置,所以它以ASCII为基础,在空置的0xA0-0xFF的范围内,加入192个字母及符号,以供使用变音符号的拉丁字母语言使用。从而支持德文,法文等。因而它依然是一个单字节编码,只是比ASCII更全面。

中文简体编码:

  • GB2312:英文占一个字节, 中文占两个字节。中国的中文编码表。
  • GBK:中国的中文编码表升级,融合了更多的中文文字符号。

中文繁体编码:

  • Big 5:每个字使用 2 bytes

国际上通用的编码:

  • Unicode:又称宽字节编码,国际标准码,融合了多种文字。所有文字都用两个字节来表示,Java语言使用的就是unicode。
  • UTF-8:自动区分中英文,英文占一个字节,中文占三个字节。
  • UTF-16: 不管英文中文都是占两个字节。

Java编码

编码功能:字符串 --> 字节数组

  • String类的getBytes() 方法进行编码,将字符串,转为对映的二进制,并且这个方法可以指定编码表。如果没有指定码表,该方法会使用操作系统默认码表。
  • 注意:中国大陆的Windows系统上默认的编码一般为GBK。在Java程序中可以使用System.getProperty(“file.encoding”)方式得到当前的默认编码。
//编码用字节数组;解码用String类;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String value = System.getProperty("file.encoding");
		System.out.println("系统默认的编码为 " + value);
				
		String str = "中国";
		byte[] buf = str.getBytes("utf-8");// 平台默认的编码表是gbk编码表,这里指定使用utf-8
		System.out.println("数组的元素:"+Arrays.toString(buf)); //输出各个元素的编码码号
				
		str = new String(buf,"utf-8");  //什么编码方式,就用什么解码方式
		System.out.println("utf-8解码后的字符串:"+ str); //编码与解码一般我们都使用统一的码表才不会出现乱码;
		str = new String(buf,"unicode");
		System.out.println("unicode解码:"+ str);  //使用unicode去解码,输出乱码;
	}
}
/* 输出:
	系统默认的编码为 GBK
	数组的元素:[-28, -72, -83, -27, -101, -67]
	utf-8解码后的字符串:中国
	unicode解码:?鮽
*/

Java解码

解码功能:字节数组 --> 字符串

  • String类的构造函数完成。
  • String(byte[] bytes) 使用系统默认码表
  • String(byte[],charset) 指定码表
  • 注意:我们使用什么字符集(码表)进行编码,就应该使用什么字符集进行解码,否则很有可能出现乱码(兼容字符集不会)。

  存文件时可以使用各种编码,但是解码的时候要对应的采用相同的解码方式。我们的字符流自动的做了编码和解码的工作,写一个中文,字符流进行了编码,存到了计算机中读到了一个字符,字符流进行了解码,我们可以看到字符。因为文件存的都是二进制。但是拷贝图片时,是纯二进制,不是有意义的字符,所以码表无法转换。

编码兼容

import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String str = "a中国"; 
		byte[] buf = str.getBytes("unicode");  //编码与解码的时候指定 的码表是unicode实际上就是用了utf-16.
		System.out.println("数组的内容:"+ Arrays.toString(buf));// -2, -1, 0, 97, 78, 45, 86, -3 :unicode编码使得开头有“-2,-1”,直接忽略其即可;
		
		str = new String(buf,"unicode");
		System.out.println("Unicode解码:"+str);  //正常显示;
		
		str = new String(buf,"utf-8");
		System.out.println("utf-8解码:"+str); //输出乱码;
	}
}
/* 输出:
	数组的内容:[-2, -1, 0, 97, 78, 45, 86, -3]
	Unicode解码:a中国
	utf-8解码:??
*/

乱码还原:

乱码还原
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Main {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String str = "大家好";
		byte[] buf = str.getBytes(); //使用gbk进行编码
		System.out.println("字节数组:"+ Arrays.toString(buf));  // -76, -13, -68, -46, -70, -61

		str = new String(buf,"iso8859-1"); //使用iso8859-1解码
		System.out.println(str); //出现乱码
		
		// 问题:出现乱码之后都可以被还原吗? ——可以,解决方案:
		byte[] buf2 = str.getBytes("iso8859-1");
		str = new String(buf2,"gbk"); 
		System.out.println(str);
	}
}
目录 缩略词 正文之前 1. 目的 2. 本文内容 3. 声明 1. 字符编码相关的背景知识 1.1. 拉丁字母 1.1.1. 我们的目标 1.2. 什么是字符编码 2. 字符编码标准 2.1. 只支持基本的拉丁字符的字符编码:ASCII 2.1.1. ASCII的由来 2.1.2. ASCII编码规则 2.1.2.1. ASCII字符集中的功能/控制字符 2.1.2.1.1. 什么是Function Code功能码或 Function Character功能字符 2.1.2.1.2. ASCII中的Function/Control Code功能字符的详细含义 2.1.2.1.2.1. 0 – NUL – NULl 字符/空字符 2.1.2.1.2.2. 1 – SOH – Start Of Heading 标题开始 2.1.2.1.2.3. 2 – STX,3 – ETX 2.1.2.1.2.4. 4 – EOT – End Of Transmission 传输结束 2.1.2.1.2.5. 5 – ENQ – ENQuiry 请求 2.1.2.1.2.6. 6 – ACK – ACKnowledgment 回应/响应 2.1.2.1.2.7. 7 – BEL – [audible] BELl 2.1.2.1.2.8. 8 – BS – BackSpace 退格键 2.1.2.1.2.9. 9 – HT – Horizontal Tab 水平制表符 2.1.2.1.2.10. 10 – LF – Line Feed 换行 2.1.2.1.2.11. 11 – VT – Vertical Tab 垂直制表符 2.1.2.1.2.12. 12 – FF – Form Feed 换页 2.1.2.1.2.13. 13 – CR – Carriage return 机器的滑动部分/底座 返回 -> 回车 2.1.2.1.2.14. 14 – SO,15 – SI 2.1.2.1.2.15. 16 – DLE – Data Link Escape 数据链路转义 2.1.2.1.2.16. 17 – DC1 – Device Control 1 / XON – Transmission on 2.1.2.1.2.17. 18 – DC2 – Device Control 2 2.1.2.1.2.18. 19 – DC3 – Device Control 3 / XOFF – Transmission off 传输中断 2.1.2.1.2.19. 20 – DC4 – Device Control 4 2.1.2.1.2.20. 21 – NAK – Negative AcKnowledgment 负面响应-> 无响应, 非正常响应 2.1.2.1.2.21. 22 – SYN – SYNchronous idle 2.1.2.1.2.22. 23 – ETB – End of Transmission Block 块传输中止 2.1.2.1.2.23. 24 – CAN – CANcel 取消 2.1.2.1.2.24. 25 – EM – End of Medium 已到介质末端,介质存储已满 2.1.2.1.2.25. 26 – SUB – SUBstitute character替补/替换 2.1.2.1.2.26. 27 – ESC – ESCape 逃离/取消 2.1.2.1.2.27. 28 – FS – File Separator 文件分隔符 2.1.2.1.2.28. 29 – GS – Group Separator分组符 2.1.2.1.2.29. 30 – RS – Record Separator记录分隔符 2.1.2.1.2.30. 31 – US – Unit Separator 单元分隔符 2.1.2.1.2.31. 32 – SP – White SPace 空格键 2.1.2.1.2.32. 127 – DEL – DELete 删除 2.1.2.1.3. 各种字符的标准的读法/叫法 2.1.3. ISO 646 2.2. 支持多种衍生拉丁字母的字符编码:EASCII和ISO 8859 2.2.1. EASCII 2.2.2. ISO 8859 2.2.2.1. ISO/IEC 8859出现的背景 2.2.2.2. ISO/IEC 8859的编码规则 2.2.2.3. ISO/IEC 8859的特点 2.2.2.4. ISO/IEC 6429 2.2.2.5. ISO 8859和ISO-8859的区别和联系 2.2.2.5.1. 原先的ISO 8859-1和我们常说的ISO 8859-1 2.3.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值