1、将字节流转换为字符流
(1)名称是前面四种抽象类的组合
(2)功能都是将字节流转换成字符流,但是没有将字符流转换成字节流的类,因为,已经获得了字符流,根本没有必要转换成字节流
(3)InputStreamReader是将InputStream中的字节转换成字符
OutputStreamWriter是将OutputStream中的字节转换成字符
(4)InputStreamReader和OutputStreamWriter两个类可以指定编码集合
(5)为什么要指定编码集合呢?
因为将字节转换成字符,读到程序中的时候,java程序在内存中的字符都是Unicode编码的但是从文件中读取的内容有自己的编码格式,可能是jbk编码,可能是ISO8859_1编码,还有可能是ASCILL编码,编码不同,所以要根据已有编码转换成Unicode编码,因此可以指定这些字符到底是什么编码格式的,但是如果指定编码格式错误的话,会出现乱码问题。
(6)怎么会出现乱码问题呢?
如果要将自己的编码转换成Unicode编码字符的话,要先确定原始字符到底是什么类型的编码,如果指定原始字符格式错误的话,会出现乱码问题。
2、实例1:TestTransform
—对TestFileInputStream的修改,可以读取文中字符(TestTileInputStream.java源代码文件中有字符、中文、英文,但是是因为按照字节来读的,读出来之后,很多中文都是乱码的,我们知道可以通过FileReader来读,同时也可以使用InputStreamReader来读)
import java.io.*;
/*对TestFileInputStream的修改,可以读取文中字符*/
public class TestTransform
{
public static void main(String[] args)
{
int b=0;
InputStreamReader isr=null;
try
{
isr=new InputStreamReader(new FileInputStream("TestTileInputStream.java"));
//通过InputStreamReader读取FileInputStream中读取的TestTileInputStream.java中的字符
long num=0;
while((b=isr.read())!=-1)
{
System.out.print((char)b);
num++;
}
System.out.println("共读取了"+num+"个字符");
}
catch(FileNotFoundException e)
{
System.out.println("找不到指定文件");
}
catch(IOException e1)
{
System.out.println("文件读取错误");
}
finally
{
try
{
isr.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
System.exit(-1);
}
}
最终正确地读取了805个字符,与字节数859不同,805个字符的字节数更多
2、实例2:TestTransform
功能:分别以中文Windows默认的GBK和ISO8859_1编码形式往文件中写入字符串
import java.io.*;
/*功能:分别以中文Windows默认的GBK和ISO8859_1编码形式往文件中写入字符串*/
public class TestTransFormEncoding {
public static void main(String[] args)
{
try
{
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("transform1.txt"));
//通过FileOutputStream文件输出流,往transform1.txt中写数据
osw.write("计算机学院");
osw.write("SUN Java");
System.out.println(osw.getEncoding());//写入的时候没有指定编码格式,那么就采用中文Window默认编码GBK
osw.close();
//FileOutputStream构造方法第二个参数的含义,是否追加
osw=new OutputStreamWriter(new FileOutputStream("transform1.txt",true),"ISO8859_1");
/*这里用FileOutputStream的重载方法,形参加了个true
* 这里本来默认是false,每次写的时候,会覆盖原来文件的内容
* 但是加了true,意思是保留原有文件内容,并且在原有文件的尾部追加新的内容
* 编码格式改成IS08859_1,指的是英文字符,没有中文字符串
* lantin-1
* */
osw.write("山东科技大学");//上面指定的编码格式中,没有文字字符串
osw.write("C#");
System.out.println(osw.getEncoding());
osw.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
第一次写的时候没有问题,第二次写的时候C#没有问题,但是“计算机学院”出现了问题,因为ISO8859_1格式中无法解码中文
3、实例3:KeyboardInput
功能:实现键盘输入功能,类似于现在的Scanner
import java.io.*;
public class KeyboardInput
{
public static void main(String[] args)
{
String s;
InputStreamReader isr=new InputStreamReader(System.in);
/*
* 本来应该套一个InputStream,但是套了System.in
* 所以System.in也是InputStream类型的
* 所以可以传给InputStreamReader
* InputStreamReader套接了控制台键盘输入
* System.in读入的是字节,InputStreamReader转换成了字符
* InputStreamReader只能一个字符一个字符地读,比较麻烦,所以又套接了一个BufferedReader
* */
BufferedReader br=new BufferedReader(isr);//BufferedReader的特点,能一次读取一行
System.out.println("Unix:Type ctrl-d or cril-c to exit."+"\nWindows:Type ctrl-z to exit");
try
{
//用Ctrl+z来结束
while((s=br.readLine())!=null)
{
System.out.println("Read: "+s);//输入一行,打印一行
}
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
try
{
br.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}
处理流怎么工作的呢?
最终打印结果