java复习第8天---8.5---IO流---转换流

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编码的文本文件

  • 分析

    1. 指定GBK编码的转换流,读取文件
    2. 指定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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gaog2zh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值