我们在没有学习字符流的时候的使用字节流读取文本文件时会出现乱码,其实出现乱码的情况不止一种,还有最常见的编码不同问题:

GBK:我们计算机默认的编码表,一个中文字符两个字节
UTF-8:万国码表,其中一个中文字符占用三个字节

因为他们每个字符占用的字节是不一样的,不同编码之间的文件在使用时会出现乱码。

字符输入转换流(InputStreamReader):

InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

看一下最常用的构造方法

我们可以看到构造方法的参数都有一个字节输入流资源
InputStreamReader(InputStream in) 
          创建一个使用默认字符集的 InputStreamReader。 
InputStreamReader(InputStream in, String charsetName) 
          创建使用指定字符集的 InputStreamReader。

来波案例看一下编码错误会出现什么情况:

java将数据转成流输出_java


这是一个UTF-8的文本文件,文件内容为:你好Java,可以看出每个中文字符占用3个字节。

接下来,我们使用eclipse默认的编码GBK来进行读取(默认编码可以操作系统和版本有关,支持手动更改)

//使用字符输入流FileReader来进行读取,打印在控制台
public class Test {
	public static void main(String[] args) {
		try(
		Reader re = new FileReader("abc.txt");
		){
			int len;
			while((len = re.read()) != -1) {
				System.out.println((char)len);
			}
			
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
}
//输出结果:
浣犲ソJava

这是什么鬼,一看就是乱码了

接下来使用字符输入转换流

public class Test {
	public static void main(String[] args) {
		try(
//注意这里的参数:它包装了低级的字符输入流,并且指定了编码	
InputStreamReader re = new InputStreamReader(new FileInputStream("abc.txt"),"UTF-8");				
		){
			int len;
			while((len = re.read()) != -1) {
				System.out.print((char)len);
			}
			
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
}
//输出结果: 你好Java

接下来谈一下

字符输出转换流(OutputStreamWriter):

我们接着上边的案例,在读取的同时我们采用eclipse默认的编码方式将它写入文件

public class Test {
	public static void main(String[] args) {
		try(
    FileReader re = new FileReader("abc.txt");				
	FileWriter ro = new FileWriter("copy.txt");	
				){
			int len;
			while((len = re.read()) != -1) {
				ro.write(len);
			}
			
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
}
//输出结果: 浣犲ソJava  乱码

我们使用转换流来进行读写操作

public class Test02 {
public static void main(String[] args) {
		try(
//按照UTF-8的编码要求进行读文件,若是读取的编码形式不正确也会出现乱码 
			InputStreamReader in = new InputStreamReader(new FileInputStream("abc.txt"),"UTF-8");
//指定编码进行输出
			OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("copy2.txt"),"GBK")
				){
			int len;
			while((len = in.read()) != -1) {
				out.write(len);
			}
			
		}catch(IOException e) {
			e.printStackTrace();
		}
}
}
//输出结果:  你好Java

转换流可以帮助我们进行读写指定的编码方式,结果不同编码读写时造成乱码的问题。