yxhxj2006

常用链接

统计

最新评论

字节流与字符流转换

字节流与字符流之间的区别却可以联系起来,这就是表中的两个类InputStreamReader和OutputStreamWriter。InputStreamReader负责把字节输入流转换为字符输入流,OutputStreamWriter负责把输出字节流转换为输出字符流。下面来看看如何进行转换。

1.字节输入流转换为字符输入流

InputStreamReader是字节流通向字符流的桥梁,它使用指定的charset读取字节并将其解码为字符。它拥有一个InputStream类型的变量,并继承了Reader,使用了对象的适配器模式,如图12-9所示。

  

根据InputStream的实例创建InputStreamReader的方法有4种:

  1. InputStreamReader(InputStream in);                
  2. //根据默认字符集创建  
  3. InputStreamReader(InputStream in, Charset cs);        
  4. //使用给定字符集创建  
  5. InputStreamReader(InputStream in, CharsetDecoder dec);    
  6. //使用给定字符集解码器创建  
  7. InputStreamReader(InputStream in, String charsetName);    
  8. //使用指定字符集创建 

后面的3个构造函数都指定了一个字符集,最后一个是最简单的,可以直接指定字符集的名称来创建,例如GB2312等。

每次调用InputStreamReader中的一个read()方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。共有3个可用的read()方法:

  1. int read();                               
  2. //读取单个字符  
  3. int read(char[] cbuf, int offset, int length);            
  4. //将字符读入数组中的某一部分  
  5. boolean ready();                              
  6. //判断此流是否已经准备好用于读取 

InputStreamReader继承自Reader,因此该类的实例可以被各种输入字符流包装。为了达到最高效率,可以考虑在BufferedReader内包装InputStreamReader。例如程序12-20所示,我们首先创建了一个FileInputStream类的实例,然后转换为InputStreamReader对象is,最后使用BufferedReader进行包装。这样就可以将字节流转换为带缓冲功能的字符流。

程序12-20  TestInputStreamReader.java

  1. public class TestInputStreamReader {  
  2.     public static void main(String[] args) {  
  3.         try {  
  4. // 创建输入流  
  5. FileInputStream fis = new FileInputStream("D:/demo/test.txt");  
  6. InputStreamReader is = new InputStreamReader(fis);  
  7. BufferedReader bis = new BufferedReader(is);  
  8.  
  9. // 从输入流读取数据  
  10. while (bis.ready()) {  
  11.     int c = bis.read();  
  12.     System.out.print((char)c);  
  13. }  
  14.  
  15. // 关闭输入流  
  16. bis.close();  
  17. is.close();  
  18. fis.close();  
  19.         } catch (IOException e) {  
  20.         }  
  21.     }  

2.字节输出流转换为字符输出流

OutputStreamWriter是字符流通向字节流的桥梁,可使用指定的charset将要写入流中的字符编码成字节。因此,它拥有一个OutputStream类型的变量,并继承了Writer,使用了对象的适配器模式,如图12-10所示。

   

根据OutputStream的实例创建OutputStreamWriter的方法有4种:

  1. OutputStreamReader(OutputStream out);                     
  2. //根据默认字符集创建  
  3. OutputStreamReader(OutputStream out, Charset cs);                 
  4. //使用给定字符集创建  
  5. OutputStreamReader(OutputStream out, CharsetDecoder dec);         
  6. //使用给定字符集解码器创建  
  7. OutputStreamReader(OutputStream out, Stroutg charsetName);        
  8. //使用指定字符集创建 

后面的3个构造函数都制定了一个字符集,最后一个是最简单的,可以直接指定字符集的名称来创建,例如GB2312等。

每次调用write()方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给write()方法的字符没有缓冲。共有3个可用的write()方法:

  1. void write(char[] cbuf, int off, int len);//写入字符数组的某一部分  
  2. void write(int c);//写入单个字符  
  3. void write(String str, int off, int len);//写入字符串的某一部分 

OutputStreamWriter继承自Writer,因此该类的实例可以被各种输出字符流包装。为了达到最高效率,可以考虑在BufferedWriter内包装OutputStreamWriter。例如程序12-21所示,我们首先创建了一个FileOutputStream类的实例,然后转换为OutputStreamReader对象os,最后使用BufferedWriter进行包装。这样就可以将字节流转换为带缓冲功能的字符流。

程序12-21  TestOutputStreamWriter.java

  1. public class TestOutputStreamWriter {  
  2. public static void main(String[] args) {  
  3. try {  
  4. // 创建输出流  
  5. FileOutputStream fos = new FileOutputStream("D:/demo/test.txt");  
  6. OutputStreamWriter os = new OutputStreamWriter(fos);  
  7. BufferedWriter bos = new BufferedWriter(os);  
  8.  
  9. // 写入数组数据  
  10. char[] buf = new char[3];  
  11. buf[0] = 'a';  
  12. buf[1] = 'b';  
  13. buf[2] = '中';  
  14. bos.write(buf);  
  15.  
  16. // 关闭输出流  
  17. bos.close();  
  18. os.close();  
  19. fos.close();  
  20. catch (IOException e) {  
  21. }  
  22. }  

posted on 2013-08-08 22:08 奋斗成就男人 阅读(5217) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: