作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦
千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者
前言
在前面的两篇文章中,壹哥给大家讲解了字节流和字符流的使用,但在进行文件读写时,如果文件的内容涉及到了中文,就有可能会出现乱码问题,这是怎么回事呢?所以在今天的文章中,壹哥会给大家分析一下计算机中的编码问题,以及在IO流中如何设置编码,快来看看吧。
------------------------------前戏已做完,精彩即开始----------------------------
全文大约【2400】 字,不说废话,只讲可以让你学到技术、明白原理的纯干货!本文带有丰富的案例及配图视频,让你更好地理解和运用文中的技术概念,并可以给你带来具有足够启迪的思考......
配套开源项目资料
Github: github.com/SunLtd/Lear…
Gitee: gitee.com/sunyiyi/Lea…
一. 编码方式
1. 简介
计算机里的任意文字和符号,在输出前其实都会设置对应的字符编码。而所谓的字符编码,则是一种将字符集中的字符映射到二进制编码的方式。而字符编码的过程又可以分为编码和解码,编码是把数据信息从一种形式或格式转换为另一种形式的过程,解码则是编码的逆过程。
在不同的字符编码中,同一个字符对应的二进制编码可能是不同的。因此,当不同的程序或操作系统使用不同的字符编码时,就可能导致字符集不兼容的问题。所以一个文本信息,在输入时采用UTF-8编码,则输出时也应该使用UTF-8解码,否则就有可能会出现乱码问题。尤其是针对中文内容,更是要保证编码和解码时采用一致的格式。这就好比两个人交谈,一个人说中文,另一个人说英语,语言不同就无法沟通。当然,有些编码之间可以相互兼容,此时同一个西文采用不同的编码可能并不会产生乱码。
2. 常用的编码格式
目前在Java开发中,比较常见的编码格式有ASCII、ISO-8859-1、GBK/GB2312、Unicode、 UTF-8、UTF-16、UTF-32等编码:
- ASCII编码: ASCII码是一种7位的编码方式,最多可以表示128种不同的字符,包括英文字母、数字和符号等。在Java中,常用的ASCII码其实是采用ISO-8859-1的编码方式。
- ISO-8859-1编码:单字节编码,是对ASCII码的扩充实现,最多可以表示0~255之间的字符范围,包括拉丁字母、希腊字母、标点符号和其他特殊符号等;
- GBK/GB2312编码:中文的国标编码,用来表示汉字,属于双字节编码。GBK可以表示简体中文和繁体中文,GB2312只能表示简体中文,GBK会兼容GB2312。
- Unicode编码:这是为解决全球字符通用编码而设计的一种编码规范,它可以表示世界上几乎所有的字符,包括中文、日文、韩文等,Java内部就采用此编码。UTF-8和 UTF-16都是对这种规范的具体实现,但此编码不兼容ISO-8859-1编码。Java中常用的Unicode编码方式是UTF-8、UTF-16和UTF-32等。其中,UTF-8是一种变长的编码方式,可以表示Unicode字符集中的任意字符,每个字符占用1~4个字节。UTF-16是一种固定长度的编码方式,每个字符占用2个字节,适合于表示中文等字符数量较少的语言。UTF-32是一种固定长度的编码方式,每个字符占用4个字节,适合于表示字符数量较多的语言。
3. Java中文乱码问题
我们在进行Java开发时,经常会遇到中文乱码,如果出现了中文乱码,可以按照以下几种方式进行解决。
3.1 setProperty方法设置编码方式
在Java程序中,我们可以使用System.setProperty()方法设置编码方式,例如:
System.setProperty("file.encoding","UTF-8");
3.2 JPanel设置中文字体
如果我们是进行JPanel开发,例如在使用JLabel和JTextField等组件时,可以使用如下代码来支持中文字体:
JLabel label = new JLabel("中文");
label.setFont(new Font("宋体", Font.PLAIN, 14));
3.3 在HTTP头信息中设置中文编码
而在进行Web开发时,可以在HTTP头信息中设置编码,如下所示:
response.setContentType("text/html;");
3.4 IO流中设置中文字符集
如果是进行IO流的开发,则需要使用正确的字符集读取和写入文件。例如,在使用InputStreamReader和OutputStreamWriter读取和写入文件时,需要指定正确的字符集,实例代码如下:
//给InputStreamReader设置编码
InputStreamReader isr = new InputStreamReader(new FileInputStream("test.txt"),"UTF-8");
//给OutputStreamWriter设置编码
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("test.txt"),"UTF-8");
二. 利用转换流设置编码
1. 概述
我们在使用IO流进行文件读写时,也经常会遇到编码问题。这是因为不同的操作系统和应用程序中,使用的字符编码可能会不同,这样在读写文件时可能会导致出现乱码或者字符集不兼容的问题。针对IO流中的乱码问题,我们可以通过指定字符编码来解决编码问题。
另外我们知道,InputStreamReader是一种用于将字节输入流转换为字符输入流的转换流, OutputStreamWriter是一种用于将字节输出流转换为字符输出流的转换流,我们使用转换流可以指定输入输出所使用的字符编码,这样就可以在一定程度上避免乱码。
2. 输入流的编码设置
比如,我们在读取文本文件时,可以使用InputStreamReader将字节流转换为字符流,并指定文件的字符编码,代码如下:
FileInputStream fis = new FileInputStream("example.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
在上面的代码中,我们使用了UTF-8编码来读取example.txt文件。如果文件使用的是其他的字符编码,我们要相应地修改字符编码。
3. 输出流的编码设置
类似地,在写入文本文件时,我们也需要指定字符编码。例如:
FileOutputStream fos = new FileOutputStream("example.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
bw.write("Hello, world!");
bw.newLine();
bw.close();
在上面的代码中,我们使用了UTF-8编码来写入文本文件。同样地,如果我们需要使用其他的字符编码,也可以相应地修改字符编码。
需要注意的是,如果文件的字符编码和指定的字符编码不匹配,就会导致读写出错或者出现乱码。因此,在进行文件读写时,一定要确认文件的字符编码,并相应地指定字符编码。
除了在读写文件时指定字符编码,还有一些其他的解决方案。例如,可以在程序中将字符编码转换为统一的编码,例如统一使用UTF-8编码。这样可以保证不同程序之间使用的字符编码一致,从而避免字符集不兼容的问题。另外,一些文本编辑器也提供了自动检测文件字符编码的功能,可以帮助我们确认文件的字符编码。
总之,我们在使用IO流进行文件读写时,要注意字符编码的问题。通过指定字符编码或者将字符编码转换为统一的编码,可以有效地避免字符集不兼容的问题。
------------------------------正片已结束,来根事后烟----------------------------
三. 结语
至此,壹哥就把Java中的编码问题给大家简单讲解了一下,现在你知道该如何设置编码格式了吗?大家要注意,实际上我们在开发时,一般都是使用IDE工具进行开发,在安装配置工具时都会统一设置常用的编码格式。壹哥在之前讲解editplus、eclipse和intellij idea时,都已经给大家讲解了如何设置全局统一的UTF-8编码格式。如果你现在想不起来,可以回过头去看看哦。
如果你独自学习觉得有很多困难,可以加入壹哥的学习互助群,大家一起交流学习。