论述题 12.  FilelnputStream和FileReader有什么区别?
【正确答案】在介绍这两个流的区别之前,首先介绍InputStream和Reader的区别。
   InputStream和Reader都可以用来读数据(从文件中读取数据或从Socket中读取数据),最主要的区别如下:InputStream用来读取二进制数(字节流),而Reader用来读取文本数据,即Unicode字符。那么二进制数与文本数据有什么区别呢?从本质上来讲,所有读取的内容都是字节,要想把字节转换为文本,需要指定一个编码方法。而Reader就可以把字节流进行编码从而转换为文本。当然,这个转换过程就涉及编码方式的问题,它默认采用系统默认的编码方式对字节流进行编码,也可以显式地指定一个编码方式,例如“UTF-8”。尽管这个概念非常简单,但是Java程序员经常会犯一些编码的错误,最常见的错误就是不指定编码方式。在读文件或从Socket读取数据的时候,如果没有指定正确的编码方式,读取到的数据可能就会有乱码,进而导致数据丢失。
   FileInputStream和FileReader有着类似的区别,它们都用于从文件中读取数据,但是FilelnputStream用于从文件中读取二进制数据(字节流),而FileReader用于从文件中读取字符数据。FileReader继承自InputStreamReader,它要么使用系统默认的编码方式,要么使用InputStreamReader所使用的编码方式。需要注意的是,InputStreamReader缓存了字符编码,因此,在创建InputStreamReader对象以后,如果再对字符编码进行修改将没有任何作用。下面给出一个使用FileInputStream和FileReader的例子:
   import java.io.FileInputStream;
   import java.io.FileReader;
   import java.io.IOException;
   public class Test{
   public static void mare(String args[])throws Exception{
   //读取字节流
   FiMnputStream fis=null;
   try{
   fis=new FilelnputStream("testInput.txt");
   intdata=fis.read();
   while(data!=-1){
   System.out.print(Integer.toHexString(data));
   data=fis.read();
   }
   }catch(IOException e){
   e.printStackTrace();
   }finally{
   if(fis!=null)
   try{
   fis.close();
   }catch(IOException e){
   }
   }
   System.out.println();
   //用FileReader读取字符
   FileReader reader=null;
   try{
   reader=new FileReader("testInput.txt");
   intcharacter=reader.read();
   while(character!=-1){
   System.out.print((char)character);
   character=reader.read();
   }
   }catch(IOException io){
   System.out.println("Failed to read character data from File");
   io.printStackTrace();
   }finally{
   if(reader!=null)
   try{
   reader.close();
   }catch(IOException e){
   }
   }
   }
   }
   程序的运行结果为:
   7465737420726561642066696c65
   test readfile
   从上面的代码可以看出,FileInputStream读取数据的方式是一个字节一个字节地读取,因此,读取速度会比较慢,同时,read方法是一个阻塞方法,它要么读取到一个字节,要么阻塞(等待可被读取的数据),这个方法的返回值为读取到的字节数,当读取到文件结尾的时候,会返回-1。在使用FilelnputStream的例子中,每个循环读取一个字节,然后转换为十六进制字符串输出。FileReader中的read方法每次读取一个字符,直到读取到文件结尾时,这个方法返回-1。
【答案解析】