一.应用场景与案例
在java.io包中,有两个类:InputStream和Reader。他们构成了io包中的输入类。
利用他们都能读取文件,InputStream是字节输入流,通过它能得到byte[],Reader是字符输入流,通过它能得到char。
Reader 用于读入16位字符,也就是Unicode 编码的字符;而 InputStream 用于读入 ASCII 字符和二进制数据。Reader支持16位的Unicode字符输出InputStream支持8位的字符输出。
Reader和InputStream分别是I/O库提供的两套平行独立的等级机构。
有时候开发人员可能得到的是InputStream对象但需要一个Reader对象,这个时候就需要类型转换。
二.案例分析与问题
分析InputStream类,它实现了Closeable接口;分析Reader类,它实现了Readable和Closeable接口。虽然它们都实现了Closeable接口,但其实在具体业务逻辑上它们并没有什么关系。
这是使用适配器模式的保证:A类和B类没有层次关系。
在java.io包中,JDK开发人员已经为我们考虑了上述问题,java.io.InputStreamReader类就是为了解决这个问题的。InputStreamReader继承了Reader类,有2个构造函数:InputStreamReader(InputStream inputStream)和InputStreamReader(InputStream inputStream,String charsetName)。InputStream就是现有对象,charsetName是Reader对象中的字符的字符集(GBK,GB2312,UTF-8等)。
具体转换过程使用StreamDecoder. forInputStreamReader(InputStream inputStream,Object object,String charsetName)等底层方法。
通过使用InputStreamReader就能完成目标:输入一个InputStream对象,得到一个Reader的子类对象InputStreamReader,即完成了类型转换工作。
三.角色描述与UML图
FileioDemo是Client;
InputStream是Adaptee;
Reader是Target;
InputStreamReader是Adapter。
四.程序源代码
package example2;
import java.io.*;
/**
* @author spencercjh
* @date 2018年6月4日23:23:05
*/
public class FileioDemo {
@SuppressWarnings("SpellCheckingInspection")
public static void main(String[] args) {
/*InputStream类实现了Closeable,Reader类实现了Readable, Closeable
* 目前已经有了一个InputStream实例对象,需要一个Reader对象
* InputStream和Reader是没有层次关系的,Closeable与此无关
* Adaptee:InputStream->Target:Reader
*/
InputStream inputStream = null;
try {
inputStream = new FileInputStream("D:/test/文件/small1.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
System.err.println("InputSteam对象建立失败!");
}
Reader reader = null;
try {
/*InputStreamReader即为适配器模式中的Adapter,继承了Target即Reader类*/
reader = new InputStreamReader(inputStream, "GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
System.err.println("read对象建立失败!");
}
try {
assert reader != null;
char result = (char) reader.read();
while (result != 0) {
System.out.print(result);
int endFlag = reader.read();
if (endFlag == -1) {
break;
} else {
result = (char) endFlag;
}
}
} catch (IOException e) {
e.printStackTrace();
System.err.println("read读失败!");
} finally {
try {
assert reader != null;
reader.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
System.err.println("read/inputstream关闭失败!");
}
}
}
}