File类与常用IO流第九章——转换流

 

  • 第九章、转换流

  • 字节编码和字符集

    • 编码:按照某种规则将字符以二进制存储到计算机中。

    • 解码:将存储在计算机中的二进制数按照某种规则解析显示出来。

    • 字符编码:Character Encoding ,就是一套自然语言与二进制数之间的对应规则。

    • 字符集:Charset,也叫编码表。是一个系统支持的所有字符的集合,包括各国文字、标点符号、图形符号、数字等。

    • 常见字符集:常见字符集有ASCII字符表、GBK字符集、Unicode字符集等。一套字符集必然至少有一套字符编码:


以下为直接复制的内容。


  • ASCII字符集:

  • ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)。

  • 基本的ASCII字符集,使用7位(bits)表示一个字符,共128字符。ASCII的扩展字符集使用8位(bits)表示一个字符,共256字符,方便支持欧洲常用字符。

  • ISO-8859-1字符集:

  • 拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。

  • ISO-8859-1使用单字节编码,兼容ASCII编码。

  • GBxxx字符集:

  • GB就是国标的意思,是为了显示中文而设计的一套字符集。

  • GB2312:简体中文码表。一个小于127的字符的意义与原来相同。但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。

  • GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等。

  • GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等。

  • Unicode字符集 :

  • Unicode编码系统为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16和UTF-32。最为常用的UTF-8编码。

  • UTF-8编码,可以用来表示Unicode标准中任何字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。所以,我们开发Web应用,也要使用UTF-8编码。它使用一至四个字节为每个字符编码,编码规则:

    • 1. 128个US-ASCII字符,只需一个字节编码。

    • 2. 拉丁文等字符,需要二个字节编码。

    • 3. 大部分常用字(含中文),使用三个字节编码。

    • 4. 其他极少使用的Unicode辅助字符,使用四字节编码。


以上为直接复制的内容


 

  • 编码引出的问题——FileReader读取项目中的文本文件

    • ANSI就是系统默认编码,在中国,是GBK

    • 由于IDEA的设置,都是默认的 UTF-8 编码,所以没有任何问题。但是,当读取Windows系统中创建的文本文件时,由于Windows系统的默认是GBK编码,就会出现乱码。

 1 import java.io.FileReader;
 2 import java.io.IOException;
 3 
 4 /*
 5     FileReader可以读取IDE默认编码格式(UTF-8)的文件
 6     FileReader读取系统默认编码(中文GBK)会产生乱码���
 7  */
 8 public class Demo01FileReader {
 9     public static void main(String[] args) throws IOException {
10         FileReader fr = new FileReader("E:\temp\\我是GBK格式的文本.txt");
11         int len = 0;
12         while((len = fr.read())!=-1){
13             System.out.print((char)len);
14         }
15         fr.close();
16     }
17 }
文件 我是GBK格式的文本.txt ,保存时选择  ANSI 格式

 

  • 转换流的原理

    • API文档中对类 FileReader 有这样的描述:用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小是适当的。要自己指定这些值,可以先在 FileInputStram 上构造一个InputStreamReader。它的的构造方法是这样的:

    •  public FileReader(String fileName) throws FileNotFoundException { super(new FileInputStream(fileName));} 
    • InputStreamReader是字节流通向字符流的桥梁:它使用指定的 cahrset读取字节并将其解码为字符,如下图所示:

  •  

  • OutputStreamWriter

    • java.io.OutputStreamWriter extends Writer,是字符流通向字节流的桥梁,可使用指定的charset将要写入流中的字符编成字节。(编码:把能看懂的变成看不懂的)。

    • 构造方法:

      • OutputStreamWriter(OutputStream out)

      • OutputStreamWriter(OutputStream out,String charsetName)

      • 构造的参数:

        • OutputStream out:字节输出流,可以用来写转换之后的字节到文件中。

        • String charsetName:指定的编码表名称,不区分大小写。不指定则默认使用UTF-8

    • 继承自父类的方法:

      • void write(int c)

      • void write(char[] cbuf)

      • abstract void write(char[] cbuf,int off,int len)

      • void write(String str)

      • void write(String str,int off,int len)

      • void flush()

      • void close()

    • 使用步骤:

      1. 创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称;

      2. 使用Osw对象中的方法write,把字符转换为字节存储在缓冲区中(编码);

      3. 使用Osw对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字的过程);

      4. 释放资源。

    • 代码:

 1 /*
 2    使用转换流OutputStreamWriter写GBK格式的文件
 3 */
 4 private static void write_gbk() throws IOException {
 5     //1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
 6     OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\gbk.txt"),"GBK");
 7     //2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)
 8     osw.write("你好");
 9     //3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
10     osw.flush();
11     //4.释放资源
12     osw.close();
13 }
 1 /*
 2     使用转换流OutputStreamWriter写UTF-8格式的文件
 3 */
 4 private static void write_utf_8() throws IOException {
 5     //1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
 6     //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\utf_8.txt"),"utf-8");
 7     OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\utf_8.txt"));//不指定默认使用UTF-8
 8     //2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)
 9     osw.write("你好");
10     //3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
11     osw.flush();
12     //4.释放资源
13     osw.close();
14 }

 

  • InputStreamReader

    • java.io.InputStreamReader extends Reader,是字节流通向字符流的桥梁,它使用指定的charset读取字节并将其解码为字符。(解码:把看不懂的编程可以看懂的。)

    • 构造方法:

      • InputStreamReader(InputStream in)

      • InputStreamReader(InputStream in,String charsetName)

      • 构造方法的参数;

        • in:字节输入流,用来读取文件中保存的字节。

        • charsetName:指定的编码表名称,不区分大小写,可以是 utf-8/UTF-8,也可以是gbk/GBK,。。。不指定则默认使用UTF-8。

    • 继承自父类的方法:

      • int read()

      • in read(char[] cbuf)

      • void close()

    • 使用步骤:

      1. 创建InputStreamReader对象,构造方法传递字节输入流和指定的编码表名称。

      2. 使用Isr对象中的方法read读取文件。

      3. 释放资源。

    • 注意事项:

      • 构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码。

    • 代码:

 1 /*
 2     使用InputStreamReader读取GBK格式的文件
 3 */
 4 private static void read_gbk() throws IOException {
 5     //1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
 6     //InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\gbk.txt"),"UTF-8");//???
 7     InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\gbk.txt"),"GBK");//你好
 8 
 9     //2.使用InputStreamReader对象中的方法read读取文件
10     int len = 0;
11     while((len = isr.read())!=-1){
12         System.out.println((char)len);
13     }
14     //3.释放资源
15     isr.close();
16 }
 1 /*
 2    使用InputStreamReader读取UTF-8格式的文件
 3 */
 4 private static void read_utf_8() throws IOException {
 5     //1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
 6      //InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\utf_8.txt"),"UTF-8");
 7      InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\utf_8.txt"));//不指定默认使用UTF-8
 8      //2.使用InputStreamReader对象中的方法read读取文件
 9      int len = 0;
10      while((len = isr.read())!=-1){
11          System.out.println((char)len);
12      }
13      //3.释放资源
14      isr.close();
15 }

 

  • 转换文件编码

    • 要求:将GBK编码的文本文件,转换为UTF-8编码的文本文件。

    • 分析:

      1. 创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK;

      2. 创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8;

      3. 使用isr对象中的方法read读取文件;

      4. 使用osw对象中的方法write,把读取到的数据写入到文件中;

      5. 释放资源。

    • 代码实现有异常则抛出:

 1 //1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK
 2 InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\我是GBK格式的文本.txt"),"GBK");
 3 //2.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8
 4 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\我是utf_8格式的文件.txt"),"UTF-8");
 5 //3.使用InputStreamReader对象中的方法read读取文件
 6 int len = 0;
 7 while((len = isr.read())!=-1){
 8      //4.使用OutputStreamWriter对象中的方法write,把读取的数据写入到文件中
 9      osw.write(len);
10 }
11 //5.释放资源
12 osw.close();
13 isr.close();

 

 
posted @ 2021-07-16 17:36  水啾2  阅读(142)  评论(0)    收藏  举报