今天学习的内容是InputStreamReader类和OutputStreamWriter类
我们知道字符流只能处理字符内容,那么如果想用字符流处理字节内容呢?这就涉及到了流的转换,Java类库提供了OutputStreamWriter类和InputStreamReader类两种适配器类用于将字节流转换为字符流。
比如:要从控制台读取用户的输入数据(注意输入的是字节数据),必须使用System.in返回的InputStream某子类的实例(字节流)。但是如果想使用字符流处理输入数据,就要使用InputStreamReader类将该字节流转换为字符流,系统底层就会使用默认编码表将字节数据解码为字符数据,这样就可以使用字符流处理输入数据了。同理,将这些数据输出到控制台(注意输出的也是字节数据)必须使用System.out返回的PrintStream的实例(PrintStream是OutputStream的子类,此实例也是字节流)。而想要处理目前的字符数据,就要使用OutputStreamWriter将字节流转换为字符流,使用字符流输出字符数据后,系统底层会使用默认编码表将字符数据再编码为字节数据。所以说:InputStreamReader类就是字节到字符的桥梁;OutputStreamWriter就是字符到字节的桥梁。
这么说有点绕,结合一个例子说明。本例的需求是从控制台获取用户输入的数据,并将用户输入的数据变为大写之后显示在控制台上,如果用户输入over,结束键盘录入。如果直接用字节流完成操作比较繁琐,而使用BufferedReader的readLine()方法就很方便。程序代码如下:
public class Test80 {
public static void main(String[] args) {
/*
* 获取用户录入的数据,并将数据变为大写的显示在控制台上,如果用户录入的是over,结束键盘录入
*/
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
// System.in返回的是InputStream某子类的实例,需要用适配器--InputStreamReader将InputStream转换为Reader
// InputStreamReader实际上就是字节到字符的“桥梁”
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
// System.out返回的是PrintStream类型(OutputStream子类)的对象,需要用适配器--OutputStreamWriter将PrintStream转换为Writer
// OutputStreamWriter实际上就是字符到字节的“桥梁”
String line = null;
try {
out.write("请输入任意小写英文语句:");
out.flush();
while ((line = in.readLine()) != null) {// 阻塞式方法
if (line.equals("over")) {// 自定义结束标记
break;
}
out.write("对应的大写语句为:" + line.toUpperCase());
out.newLine();
out.write("请输入任意小写英文语句:");
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();// 如果流一直在进行等待用户输入和打印用户输入数据的循环动作,不会关闭流
// 不过本例中自定义了跳出循环的条件,程序跳出循环后会关闭流
} catch (IOException e) {
throw new RuntimeException("关闭资源失败");
}
}
if (out != null) {
try {
out.write("流关闭!");
out.close();// 如果流一直在进行等待用户输入和打印用户输入数据的循环动作,不会关闭流
// 不过本例中自定义了跳出循环的条件,程序跳出循环后会关闭流
} catch (IOException e) {
throw new RuntimeException("关闭资源失败");
}
}
}
}
}
类似此需求,只要是涉及到使用字符流处理字节内容,都可以使用流的转换完成,比如:
1.将用户输入写到文本文件中
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutStream("xxx.txt")));
2.将文本文件的内容写到控制台
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("xxx.txt")));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
3.复制文本文件
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("xxx.txt")));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutStream("xxx.txt")));
下面到了解坑时间 既然包括文本文件,所有文件都是以字节的形式存储在硬盘中的,那么FileWriter类和FileReader类是如何操作文本文件的呢?答案就是:FileWriter类和FileReader类分别是OutputStreamWriter类和InputStreamReader类的子类!流的转换过程已经自动完成了!实际上new InputStreamReader(new FileInputStream("xxx.txt"))与new FileReader("xxx.txt")、new OutputStreamWriter(new FileOutStream("xxx.txt"))与new FileWriter("xxx.txt")都是等价的!