I/O复习四 字符流 InputStreamReader/OutputStreamWriter

在使用字节流读取文件时,如果文件中含有汉字,读取方式又是一个字节一个字节的读取方式时,必然会出现乱码。
* 因为字节流每次只能处理一个字节的数据,即ASC2字符,而每个汉字占两个字节,因此使用字节流处理中文时很容易就出现了乱码。
*
* 而字符流处理类就是专门处理这类问题的,它们是由Reader/Writer类为基础派生出的一系列的类。和InputStream/OutputStream
* 一样Reader/Writer也是抽象类,只提供了一系类处理字符的接口。它们的方法与InputStream和OutputStream类似只不过其中的参
* 数换成字符或者字符数组。
*
* InputStreamReader/OutputStreamWriter 是java.io包中处理字符的最基本的类,用来在字节流和字符流之间作为中介:从字节输入流读入字节时,
* 按编码规范转换为字符;往字节输出流写入字符时将按照编码规范转换为字符,可以说它们是从字节流到字符流的一一转换。
*
* Demo:将磁盘上的文件输出到控制台 并复制到新文件中去!

 1 package com.tai.io;
 2 
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.FileNotFoundException;
 6 import java.io.FileOutputStream;
 7 import java.io.FileReader;
 8 import java.io.InputStreamReader;
 9 import java.io.OutputStreamWriter;
10 
11 public class InputStreamReaderDemo
12 {
13     /**
14      * 在使用字节流读取文件时,如果文件中含有汉字,读取方式又是一个字节一个字节的读取方式时,必然会出现乱码。
15      * 因为字节流每次只能处理一个字节的数据,即ASC2字符,而每个汉字占两个字节,因此使用字节流处理中文时很容易就出现了乱码。
16      * 
17      * 而字符流处理类就是专门处理这类问题的,它们是由Reader/Writer类为基础派生出的一系列的类。和InputStream/OutputStream
18      * 一样Reader/Writer也是抽象类,只提供了一系类处理字符的接口。它们的方法与InputStream和OutputStream类似只不过其中的参
19      * 数换成字符或者字符数组。
20      * 
21      * InputStreamReader/OutputStreamWriter 是java.io包中处理字符的最基本的类,用来在字节流和字符流之间作为中介:从字节输入流读入字节时,
22      * 按编码规范转换为字符;往字节输出流写入字符时将按照编码规范转换为字符,可以说它们是从字节流到字符流的一一转换。
23      * 
24      * Demo:将磁盘上的文件输出到控制台 并复制到新文件中去!
25      */
26     static InputStreamReader reader = null;
27     static OutputStreamWriter writer = null;
28     public static void main(String[] args) throws Exception
29     {
30         reader = new InputStreamReader(new FileInputStream("c:/abc/abc.txt"));
31         writer = new OutputStreamWriter(new FileOutputStream("c:/abc/abcd.txt"));
32         char[] ch = new char[1024];
33         int len = 0;
34         StringBuffer buffer = new StringBuffer();
35         while(-1!=(len = reader.read(ch,0,40)))
36         {
37             String str = new String(ch,0,len);
38             System.out.println(str);
39 //            buffer.append(str);
40             writer.write(ch, 0, len);
41         }
42         
43 //        System.out.println(buffer);
44         writer.close();
45         reader.close();
46     }
47 }
InputStreamReader/OutputStreamWriter

输出结果

幕落无声,我独自站在阳台,眺望着即将远离的一天……

夕阳,很美,带着橘红色
的余晖,染红了半天的晚霞。莫然,有点害怕夜幕的到来,害怕那一望无际的黑暗。只因黑
暗中,我无法捕捉你的聘婷的背影从我身边掠过的瞬间,无法看清你精致的脸庞带着那一份
抹不去的忧伤与忧愁。

无边的夜晚,无声的助长了数不清的思念,平添了说不出的
寂寥。冬季的黄昏,空气中多了一股寒冷的萧瑟,多了一份冬季特有的寒意。寒风萧索,往
事如烟。我抬头望向远方,想起了那些青葱过往。

同时,会产生新的文本文件 abcd.txt

在写的时候第一次我遇到了一个很粗心的错误,在输出到控制台的时候  刚开始在最后一行会产生许多小方框 ,然后我把char数组的长度写的小点,在最后一样又会产生重复

这是因为:

读取的时候,会将读取出来的第一个直接存储在char数组的0位置,下一个存储在1位置,以此类推 。。。如果最后吃读取的长度少于定义数组的长度的话,新的内容也就不会把上一次数组里的值全部覆盖掉,就会产生我所谓的重复,

但是如果数组长度很长,读取的内容都没有填满整个数组,数组后面也就是空白了 在转化为字符串输出时就会出现我所谓的小方框....

而解决这个问题很简单,就是把 在产生字符串的时候与写入时一样把转换、写入的长度都精确到最后一次读取的末尾在数组中的位置   new String(bt,0,len);

len就是InputSreamReader类read()的返回值

可以查看API  上面是这样解释这个返回值的:

The number of characters read, or -1 if the end of the stream has been reached

原文地址:https://www.cnblogs.com/mauiie/p/3526946.html