字符编码与字符集、转换流(InputStreamReader、OutputStreamWriter)

1.字符编码
编码:字符(能看懂的)-->字节(看不懂的)
解码:字节(看不懂的)-->字符(能看懂的)
乱码:按照A规则存储,同样按照A规则解析,那么会显示正确的文本符号;
反之,按照A规则存储,再按B规则解析,会导致乱码现象。
字符编码(Character Encoding):就是一套自然语言的字符与二进制数之间的对应规则
编码表:生活中文字和计算机中二进制的对应规则

2.字符集就是编码表,是系统所有字符的集合,包括各个国家文字、标点符号、图形符号、数字

 

 

 

 

 

 编码引发的乱码问题:

package iotest.bufferedIOtest;
/*FileReader在IDEA中默认的编码格式为UTF-8
* FileReader读取系统默认编码(GBK),会出现乱码
* */

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;

public class ErrorCodeTest {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("C:\\test\\系统默认GBK编码文本1.txt");
        int len =0;
        while ((len = fr.read()) != -1){
            System.out.print((char) len);
        }
        fr.close();
    }
}

运行结果为:

 

源文件内容为:

 

乱码问题解决方法:用转换流

转换流的强大之处为:可以指定编码表(OutputStreamWriter、InputStreamReader可指定特定的编码表)

GBK编码中,一个中文占两个字节
UTF-8编码中,一个中文占三个字节

OutputStreamWriter 类
java.io.OutputStreamWriter extends writer
OutputStreamWriter:是字符流向字节的桥梁,可使用指定的charset将要写入流中的字符编码成字节(编码:把能看懂的变成看不懂的)
写在硬盘上的都是字节,当打开文件时,会调用系统的编码表来解码
构造方法:
public OutputStreamWriter(OutputStream out, String charsetName)
public OutputStreamWriter(OutputStream out)--默认编码表为UTF-8
参数:
OutputStream out:字节输出流,可以把转换之后的字节写入到指定文件
String charsetName:指定编码表名称,不区分大小写,utf-8/UTF-8,gbk/GBK都行

使用步骤:
1.创建OutputStreamWriter对象,构造方法中传递指定的字节输出流和指定的编码表名称
2.使用OutputStreamWriter的write方法,将字符转化为字节,存储在缓冲区中(编码)
3.使用OutputStreamWriter的flush方法,将内存中的字节写到硬盘文件中(使用字节流写的过程)
4.释放资源

package iotest.changeeachother;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class TestOutputStreamWriter01 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("C:\\test\\h.txt");
        OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");//编码表用的是GBK,也可以写UTF-8
        osw.write("你好啊",0,2);
        osw.write("就你那女女女");
        osw.close();
    }
}

 

InputStreamReader类
java.io.InputStreamReader extends Reader
InputStreamReader:是字节流向字符的桥梁,可使用指定的charset将要写入流中的字节编码成字符
从硬盘上读取的都是字节,此时编码表以确定,需要与源文件编码表相一致
构造方法:
public InputStreamReader(InputStream in)
public InputStreamReader(InputStream in, String charsetName)
参数:
InputStream in:字节输入流,可以将硬盘上的文件以字节的形式读取到内存中
String charsetName:指定编码表名称,不区分大小写,utf-8/UTF-8,gbk/GBK都行
使用步骤:
1.创建InputStreamReader对象,构造方法中传递指定的字节输入流和指定的编码表名称
2.使用InputStreamReader的read方法,将字节转化为字符,放在内存中使用(解码)
3.释放资源
注意事项
构造方法中的指定的编码表名称要与源文件的编码表名称相同,否则会出现乱码
(系统已经按系统的编码表进行编译成字节,此时若用不一样的编码表,会出现乱码)

package iotest.changeeachother;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class TestInputStreamReader01 {
    public static void main(String[] args) throws IOException {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\test\\系统默认GBK编码文本1.txt"),"utf-8");//源文件使用的编码表为GBK,而此时设置为utf-8,会出现乱码
        int len = 0;                                                                                                  //若设置为GBK,不会出现乱码
        while ((len = isr.read()) != -1){
            System.out.print((char) len);
        }

        isr.close();
    }
}

运行结果

 


练习:转换文件编码:将GBK编码文件转化为UTF-8编码的文件

package iotest.changeeachother;

import java.io.*;

//转换文件编码:将GBK编码文件转化为UTF-8编码的文件
public class GBKtoUtf {
    public static void main(String[] args) throws IOException {
        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("C:\\test\\GBK文件.txt"),"GBK");//这里必须是GBK
        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream("C:\\test\\UTF-8文件.txt"),"UTF-8");

        int len = 0;
        while ((len = inputStreamReader.read()) != -1){
            outputStreamWriter.write(len);
        }
        outputStreamWriter.close();
        inputStreamReader.close();
    }
}

 

posted @ 2020-07-31 20:22  DannyBoy~  阅读(1410)  评论(0编辑  收藏  举报