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 }
输出结果
幕落无声,我独自站在阳台,眺望着即将远离的一天……
夕阳,很美,带着橘红色
的余晖,染红了半天的晚霞。莫然,有点害怕夜幕的到来,害怕那一望无际的黑暗。只因黑
暗中,我无法捕捉你的聘婷的背影从我身边掠过的瞬间,无法看清你精致的脸庞带着那一份
抹不去的忧伤与忧愁。
无边的夜晚,无声的助长了数不清的思念,平添了说不出的
寂寥。冬季的黄昏,空气中多了一股寒冷的萧瑟,多了一份冬季特有的寒意。寒风萧索,往
事如烟。我抬头望向远方,想起了那些青葱过往。
同时,会产生新的文本文件 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