Java 7之传统I/O - InputStreamReader和OutputStreamWriter

OutputStreamWriter 作用和原理都比较简单。就是将“字节输出流”转换成“字符输出流”。它的原理是,我们创建“字符输出流”对象时,会指定“字节输出流”以及“字符编码”。来看一下源代码,如下:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. // 将“字节输出流”转换成“字符输出流”    
  2. public class OutputStreamWriter extends Writer {    
  3.    
  4.     private final StreamEncoder se;  // 字符到字节要进行解码  
  5.    
  6.     // 根据out创建OutputStreamWriter,使用编码charsetName   
  7.     public OutputStreamWriter(OutputStream out, String charsetName) throws UnsupportedEncodingException {    
  8.         super(out);    
  9.         if (charsetName == null)    
  10.             throw new NullPointerException("charsetName");    
  11.         se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);    
  12.     }    
  13.    
  14.     // 根据out创建OutputStreamWriter,使用默认的编码    
  15.     public OutputStreamWriter(OutputStream out) {    
  16.         super(out);    
  17.         try {    
  18.             se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);    
  19.         } catch (UnsupportedEncodingException e) {    
  20.             throw new Error(e);    
  21.         }    
  22.     }    
  23.    
  24.     // 根据out创建OutputStreamWriter,使用编码cs    
  25.     public OutputStreamWriter(OutputStream out, Charset cs) {    
  26.         super(out);    
  27.         if (cs == null)    
  28.             throw new NullPointerException("charset");    
  29.         se = StreamEncoder.forOutputStreamWriter(out, this, cs);    
  30.     }    
  31.    
  32.     // 根据out创建OutputStreamWriter,使用编码器enc    
  33.     public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {    
  34.         super(out);    
  35.         if (enc == null)    
  36.             throw new NullPointerException("charset encoder");    
  37.         se = StreamEncoder.forOutputStreamWriter(out, this, enc);    
  38.     }  
  39.    
  40.     // 获取编码器enc    
  41.     public String getEncoding() {    
  42.         return se.getEncoding();    
  43.     }    
  44.    
  45.     // 刷新缓冲区    
  46.     void flushBuffer() throws IOException {    
  47.         se.flushBuffer();    
  48.     }    
  49.    
  50.     // 将单个字符写入到OutputStreamWriter中    
  51.     public void write(int c) throws IOException {    
  52.         se.write(c);    
  53.     }    
  54.    
  55.     // 将字符数组cbuf从off开始的数据写入到OutputStreamWriter中,写入长度是len    
  56.     public void write(char cbuf[], int off, int len) throws IOException {    
  57.         se.write(cbuf, off, len);    
  58.     }    
  59.    
  60.     // 将字符串str从off开始的数据写入到OutputStreamWriter中,写入长度是len    
  61.     public void write(String str, int off, int len) throws IOException {    
  62.         se.write(str, off, len);    
  63.     }   
  64.    
  65.     // 刷新“输出流”    
  66.     // 它与flushBuffer()的区别是:flushBuffer()只会刷新缓冲,而flush()是刷新流,flush()包括了flushBuffer    
  67.     public void flush() throws IOException {    
  68.         se.flush();    
  69.     }    
  70.    
  71.     // 关闭“输出流”    
  72.     public void close() throws IOException {    
  73.         se.close();    
  74.     }    
  75. }   
编写测试用例,如下:
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. private static final String CharsetName = "utf-8"// 使用支持中文编码的格式  
  2.   
  3. private static void testWrite() {  
  4.     File file = new File("C:\\test.txt");  
  5.     try(OutputStreamWriter out1 = new OutputStreamWriter(new FileOutputStream(file), CharsetName);) {  
  6.         out1.write("积小流以成江海");             // 写入10个汉字  
  7.         out1.write("abcdefg\n");                  // 输出内容还有一个换行符"\n"  
  8.     } catch(IOException e) {  
  9.         e.printStackTrace();  
  10.     }  
  11. }  
输出结果如下:
积小流以成江海abcdefg(由于输入内容还有一个换行符,所以光标会定位到下一行)

InputStreamReader的作用与OutputStreamWriter的作用类似,只是将字节输入流转换为字符输入流。源代码如下:
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. // 将“字节输入流”转换成“字符输入流”    
  2. public class InputStreamReader extends Reader {    
  3.    
  4.     private final StreamDecoder sd;  // 字节到字符要进行编码  
  5.    
  6.     // 根据in创建InputStreamReader,使用默认的编码    
  7.     public InputStreamReader(InputStream in) {    
  8.         super(in);    
  9.         try {    
  10.             sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object    
  11.         } catch (UnsupportedEncodingException e) {    
  12.             throw new Error(e);    
  13.         }    
  14.     }    
  15.    
  16.     // 根据in创建InputStreamReader,使用编码charsetName(编码名)    
  17.     public InputStreamReader(InputStream in, String charsetName)    
  18.         throws UnsupportedEncodingException    
  19.     {    
  20.         super(in);    
  21.         if (charsetName == null)    
  22.             throw new NullPointerException("charsetName");    
  23.         sd = StreamDecoder.forInputStreamReader(in, this, charsetName);    
  24.     }    
  25.    
  26.     // 根据in创建InputStreamReader,使用编码cs    
  27.     public InputStreamReader(InputStream in, Charset cs) {    
  28.         super(in);    
  29.         if (cs == null)    
  30.             throw new NullPointerException("charset");    
  31.         sd = StreamDecoder.forInputStreamReader(in, this, cs);    
  32.     }    
  33.    
  34.     // 根据in创建InputStreamReader,使用解码器dec    
  35.     public InputStreamReader(InputStream in, CharsetDecoder dec) {    
  36.         super(in);    
  37.         if (dec == null)    
  38.             throw new NullPointerException("charset decoder");    
  39.         sd = StreamDecoder.forInputStreamReader(in, this, dec);    
  40.     }    
  41.    
  42.     // 获取解码器    
  43.     public String getEncoding() {    
  44.         return sd.getEncoding();    
  45.     }    
  46.    
  47.     // 读取并返回一个字符    
  48.     public int read() throws IOException {    
  49.         return sd.read();    
  50.     }    
  51.    
  52.     // 将InputStreamReader中的数据写入cbuf中,从cbuf的offset位置开始写入,写入长度是length    
  53.     public int read(char cbuf[], int offset, int length) throws IOException {    
  54.         return sd.read(cbuf, offset, length);    
  55.     }    
  56.    
  57.     // 能否从InputStreamReader中读取数据    
  58.     public boolean ready() throws IOException {    
  59.         return sd.ready();    
  60.     }    
  61.    
  62.     // 关闭InputStreamReader    
  63.     public void close() throws IOException {    
  64.         sd.close();    
  65.     }    
  66. }   

编写测试用例,如下:
[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. private static void testRead() {  
  2.     File file = new File("C:\\test.txt");  
  3.       try ( InputStreamReader isr = new InputStreamReader(new FileInputStream(file), CharsetName);){  
  4.   
  5.           System.out.println("value1="+(char)isr.read());// 读取一个字节  
  6.   
  7.           isr.skip(6);                  // 跳过4个字节进行读取  
  8.           System.out.println("value2="+(char)isr.read());  
  9.   
  10.           char[] buf = new char[10];  
  11.           isr.read(buf, 0, buf.length); // 读取10个字符到buf数组中  
  12.           System.out.println("buf="+(new String(buf)));  
  13.   
  14.       } catch(IOException e) {  
  15.           e.printStackTrace();  
  16.       }  
  17.   }  
其中文件中的内容为:abcdefghigkl
最后的输出结果如下:
value1=a
value2=h
buf=igkl
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值