java复习第8天---8.5---IO流---转换流
目录
文章目录
内容
1、字符编码和字符集
1.1、字符编码
计算机中存储数据都是用二进制表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等符号都是二进制转换之后的结果。按照某种规则,将字符存储到计算机中,称之为编码。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码。比如按照A规则编码,同样按照A规则解码,则显示正确的文本符号;如果按照B规则解码,则会导致乱码。
-
编码:字符(人看懂的) ----> 字节(计算机能理解的)
-
解码:字节 -----> 字符
-
字符编码:一套自然语言的字符和二进制数之间的对应规则
-
编码表:自然语言的字符和二进制数之间对应规则表
1.2、字符集
字符集,也称编码表,是所有计算机支持的字符合集,包含国家符号,标点符号,图形符合、数字等。
计算机要存储和识别各种字符,需要进行字符编码。一套字符集必然至少有一套字符编码。常用的字符集:
- ASCII字符集
- 简介:American Standard Code for Information Interchange,美国信息标准交换码。
- 编码:ASCII编码
- GBK字符集
- 简介:中文国标码
- 编码:GBK编码
- Unicode字符集:
- 简介:为表达任意语言字符而设计,是业界标准,称为统一码,也称万国码。
- 编码:
- UTF-8编码
- UTF-16编码
- UTF-32编码
可见,当指定了编码,它对应的字符集也就确定了,所以我们需要关心的是编码。
2、编码不一致导致的问题
国内windows默认字符集为GBK,而通常使用的IDE编码默认为UTF-8,这就导致处理中文的时候,经常出现乱码;
-
示例2-1:读取GBK编码的e.txt内容
package io.stream.change; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class TestLunCode1 { public static void main(String[] args) throws IOException { String path = "f:\\test\\e.txt"; BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path)); int len; while((len = bis.read()) != -1) { System.out.print((char)len); } bis.close(); } } 测试结果: e.txt 原文: + 使用步骤 1. 创建文件输出流对象,指定写入文件 2. 调用write方法把数据写入文件 3. 调用close方法关闭输出流释放相关的系统资源 输出显示结果: + ???????è 1. ???¨?????????÷???ó?????¨???????? 2. ?÷??write·?·¨°????????????? 3. ?÷??close·?·¨??±??????÷??·??à????????×???
-
解析:
- GBK用二个字节表示一个中文
- 读取中文的时候,是一个字节一个字节读取,那么解析的时候,自然不会是中文
3、转换流原理
GBK编码用2个字节表示一个中文,UTF-8使用3个字节表示一个中文。当存储为GBK编码时,转换流读取2个字节,通过补全3个字节,显示为UTF-8的3个字节中文。写入时也是如此。
4、OutputStreamWriter
-
概述:public class OutputStreamWriter
extends WriterOutputStreamWriter是字符的桥梁流以字节流:向其写入的字符编码成使用指定的字节charset 。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。 -
原理:每次调用write()方法都会使编码转换器在给定字符上被调用。 所得到的字节在写入底层输出流之前累积在缓冲区中。 可以指定此缓冲区的大小,但是默认情况下它大部分用于大多数目的。 请注意,传递给write()方法的字符不会缓冲。
-
建议:为了最大的效率,请考虑在BufferedWriter中包装一个OutputStreamWriter,以避免频繁的转换器调用。 例如:
Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
-
示例4-1:把“为了最大的效率,请考虑在BufferedWriter中包装一个OutputStreamWriter,以避免频繁的转换器调用”这句话写入b.txt,本地为GBK编码
package io.stream.change; import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; public class TestOutputStreamWriter1 { public static void main(String[] args) throws IOException { String path = "f:\\test\\b.txt"; BufferedWriter bos = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path))); bos.write("为了最大的效率,请考虑在BufferedWriter中包装一个OutputStreamWriter,以避免频繁的转换器调用".toCharArray()); bos.close(); } } 测试结果:b.txt 为了最大的效率,请考虑在BufferedWriter中包装一个OutputStreamWriter,以避免频繁的转换器调用
5、InputStreamReader
-
概述:public class InputStreamReader
extends ReaderInputStreamReader是从字节流到字符流的桥:它读取字节,并使用指定的charset将其解码为字符 。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。 -
原理解析:每个调用InputStreamReader的read()方法之一可能会导致从底层字节输入流读取一个或多个字节。 为了使字节有效地转换为字符,可以从底层流读取比满足当前读取操作所需的更多字节。
-
建议:为了最大的效率,请考虑在BufferedReader中包装一个InputStreamReader。 例如:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
-
示例5-1:读取GBK编码存储的e.txt并正确显示
package io.stream.change; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; public class TestInputStreamReader1 { public static void main(String[] args) throws IOException { String path = "f:\\test\\e.txt"; BufferedReader bis = new BufferedReader(new InputStreamReader(new FileInputStream(path))); int len; while((len = bis.read()) != -1) { System.out.print((char)len); } bis.close(); } } 测试结果: + 使用步骤 1. 创建文件输出流对象,指定写入文件 2. 调用write方法把数据写入文件 3. 调用close方法关闭输出流释放相关的系统资源
6、小案例
-
需求:将GBK编码的文本文件,转换为UTF-8编码的文本文件
-
分析
- 指定GBK编码的转换流,读取文件
- 指定UTF-8编码的转换流,写入文件
-
代码6-1:
package io.stream.change; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class TestCodeInterchange { public static void main(String[] args) throws IOException, FileNotFoundException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("f:\\test\\a.txt"), "GBK")); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("f:\\test\\b.txt"), "UTF-8")); String len; while((len = br.readLine()) != null) { bw.write(len); bw.newLine(); } br.close(); bw.close(); } } 测试结果: b.txt 打开--->文件--->另存为 查看编码ANSI 本地编码也就是GBK 欢迎入坑JAVA! 《JAVA从入门到放弃》 Java PHP C++ b.txt 打开--->文件--->另存为 查看编码为UTF-8 欢迎入坑JAVA! 《JAVA从入门到放弃》 Java PHP C++
后记 :
本项目为参考某马视频开发,相关视频及配套资料可自行度娘或者联系本人。上面为自己编写的开发文档,持续更新。欢迎交流,本人QQ:806797785
前端项目源代码地址:https://gitee.com/gaogzhen/vue-leyou
后端JAVA源代码地址:https://gitee.com/gaogzhen/JAVA