简介

OutputStreamWriter和InputStreamReader是字节流和字符流转化之间桥梁,OutputStreamWriter继承自Writer接口,而InputStreamReader继承自接口Reader.需要了解的一点是字符流的写入和读取的方式.

  • 字符输出流:将字符通过指定编码方式转化成字节数据,然后存储到文件中.
  • 字符输入流:读取文件的字节数据通过相同的编码方式转化成字符.不同的编码方式会造成乱码.

1.InputStreamReader是字节流转化成字符流的桥梁.通过给定字符编码方式或者传入指定编码方式,平台默认编码方式等将字节转化成字符读取到流中.子类有FileReader.

2.OutputStreamWriter是字符流转化成字节流的桥梁,通过给定字符编码方式或者传入指定编码方式,平台默认编码方式等将字符转化成字节写到流中.子类有FileWriter.

OutputStreamWriter介绍

1.构造方法.

public OutputStreamWriter(OutputStream out, String charsetName){}
public OutputStreamWriter(OutputStream out) {}
public OutputStreamWriter(OutputStream out, Charset cs) {}
public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {}

四个有参构造方法,区别是编码传入方式.分别是:

  • 创建一个指定了底层字节输出流和"指定"字符编码名称charsetName的OutputStreamWriter流.
  • 创建一个指定了底层字节输出流和默认字符编码方式的OutputStreamWriter流.
  • 创建一个指定底层字节输出流和"给定"字符编码方式cs的OutputStreamWriter流.
  • 创建一个 指定底层字节输出流和"给定"字符编码器enc的OutputStreamWriter流.

2.内部变量

private final StreamEncoder se;
  • 负责字符编码的类StreamEncoder.

3.内部方法

public String getEncoding()
public void write(int c){}
public void write(char cbuf[], int off, int len){}
public void write(String str, int off, int len){}
public void flush() {}
public void close() {}
  • getEncoding()----获取字符编码方式.
  • write(int c)---将单个字符写到流中.
  • write(char cbuf[],int off,int len)--将字符数组cbuf中,off位置开始,len个字符写到流中.
  • write(String str,int off,int len)---将字符串str中,off位置开始,len个字符写到流中.
  • flush()---刷新流.
  • close()---关闭流,释放相关资源.

InputStreamReader介绍

1.构造方法.

public InputStreamReader(InputStream in) {}
public InputStreamReader(InputStream in, String charsetName){}
public InputStreamReader(InputStream in, Charset cs) {}
public InputStreamReader(InputStream in, CharsetDecoder dec) {}

与OutputStreamWriter流相对应的四种有参构造方法,根据对应的字符编码方式将数据解码读取.

  • 创建一个指定了底层字节输出流和默认字符编码方式的InputStreamReader流.
  • 创建一个指定了底层字节输出流和"指定"字符编码名称charsetName的InputStreamReader流.
  • 创建一个指定底层字节输出流和"给定"字符编码方式cs的InputStreamReader流.
  • 创建一个 指定底层字节输出流和"给定"字符编码器dec的InputStreamReader流.

2.内部变量

private final StreamDecoder sd;
  • 负责字符解码的类StreamDecoder.

3.内部方法

public String getEncoding() {}
public int read(){}
public int read(char cbuf[], int offset, int length){}
public boolean ready(){}
public void close(){}
  • getEncoding()---获取字符编码方式
  • read()---从流中读取单个字符.
  • read(char cbuf[],int offset,int length)---将流中length个字符读取到字符数组cbuf中,cbuf中从offset位置开始
  • ready()---流是否准备读取,读取缓冲区不为空或者底层输入流中可读取数据时返回true.
  • close()---关闭流,释放相关资源.

案例

public class InputStreamDemo {public static void main(String[] args) throws IOException {String charsetName="UTF-8";testOutputStreamWriter(charsetName);testInputStreamReader(charsetName);}private static void testOutputStreamWriter(String charsetName) throws IOException {char[] cbuf = new char[] {'h','e','l','l','o','w','o','r','l','d'};OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\java.txt"),charsetName);osw.write("0123456789", 0, 8);osw.write(cbuf, 1, 6);osw.write('h');osw.close();}private static void testInputStreamReader(String charsetName) throws IOException {InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\java.txt"),charsetName);int read = isr.read();System.out.println("单个字符--------"+(char)read);char[] cbuf = new char[1024];isr.read(cbuf, 0, 10);System.out.println(new String(cbuf));String encoding = isr.getEncoding();System.out.println("解码方式--------"+encoding);isr.close();}
}

运行结果:

单个字符--------0
1234567ell
解码方式--------UTF8

源码分析

1.InputStreamWriter源码分析

public class OutputStreamWriter extends Writer {//负责编码的类StreamEncoderprivate final StreamEncoder se;//创建一个指定字节输出流和"指定"的字符编码名称的OutputStreamWriter流.public OutputStreamWriter(OutputStream out, String charsetName)throws UnsupportedEncodingException{super(out);if (charsetName == null)throw new NullPointerException("charsetName");se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);}//创建一个指定字节输出流和默认编码方式的OutputStreamWriter流.public OutputStreamWriter(OutputStream out) {super(out);try {se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);} catch (UnsupportedEncodingException e) {throw new Error(e);}}//创建一个指定字节输出流和"给定"字符编码方式的OutputStreamWriter流.public OutputStreamWriter(OutputStream out, Charset cs) {super(out);if (cs == null)throw new NullPointerException("charset");se = StreamEncoder.forOutputStreamWriter(out, this, cs);}//创建一个指定字节输出流和"给定"编码器的OutputStreamWriter流.public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {super(out);if (enc == null)throw new NullPointerException("charset encoder");se = StreamEncoder.forOutputStreamWriter(out, this, enc);}//获取编码方式.public String getEncoding() {return se.getEncoding();}//刷新输出缓冲数据到底层字节流中void flushBuffer() throws IOException {se.flushBuffer();}//将单个字符写到流中public void write(int c) throws IOException {se.write(c);}//将字符数组cbuf中,off位置开始,len个字符写到流中public void write(char cbuf[], int off, int len) throws IOException {se.write(cbuf, off, len);}//将字符串中off位置开始,len个字符写到流中public void write(String str, int off, int len) throws IOException {se.write(str, off, len);}//刷新流public void flush() throws IOException {se.flush();}//关闭流,释放相关资源public void close() throws IOException {se.close();}
}

2.InputStreamReader源码分析

public class InputStreamReader extends Reader {//负责解码的类StreamDecoderprivate final StreamDecoder sd;//创建一个指定了底层字节输入流和默认字符编码方式的InputStreamReader流public InputStreamReader(InputStream in) {super(in);try {sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object} catch (UnsupportedEncodingException e) {// The default encoding should always be availablethrow new Error(e);}}//创建一个指定了底层字节输入流和"指定"字符集编码方式的InputStreamReader流public InputStreamReader(InputStream in, String charsetName)throws UnsupportedEncodingException{super(in);if (charsetName == null)throw new NullPointerException("charsetName");sd = StreamDecoder.forInputStreamReader(in, this, charsetName);}//创建一个指定了底层 字节输入流和"给定"字符编码方式的InputStreamReader流.public InputStreamReader(InputStream in, Charset cs) {super(in);if (cs == null)throw new NullPointerException("charset");sd = StreamDecoder.forInputStreamReader(in, this, cs);}//创建一个指定了底层字节输入流和"给定"字符集编码器的InputStreamReader流.public InputStreamReader(InputStream in, CharsetDecoder dec) {super(in);if (dec == null)throw new NullPointerException("charset decoder");sd = StreamDecoder.forInputStreamReader(in, this, dec);}//获取流使用的字符编码方式public String getEncoding() {return sd.getEncoding();}//从流中读取单个字符public int read() throws IOException {return sd.read();}//从InputStreamReader流中读取字符数据到字数数组cbuf中,cbuf中位置从offset开始,长度为length个字符public int read(char cbuf[], int offset, int length) throws IOException {return sd.read(cbuf, offset, length);}//流是否准备读取,读取缓冲区不为空或者底层输入流中可读取数据时返回true.public boolean ready() throws IOException {return sd.ready();}//关闭流,释放相关资源public void close() throws IOException {sd.close();}
}

总结

InputStreamReader流和OutputStreamWriter流作为字节和字符转换的桥梁,需要知道字符是以指定的编码方式存储到文件中,同理读取文件的时候,通过相同的编码方式进行解码成字符,读取到内存或者程序中.其中"指定的编码方式''在创建流的时候需要指定,否则是默认的编码方式(GBK).

Java IO流之OutputStreamWriter和InputStreamReader分析相关推荐

  1. java IO流 练习题 分析成绩单

    java IO流 练习题 题目要求: 分析成绩单. 现在有如下格式的成绩单(文本格式)score.txt: 姓名:张三,数学72分,物理67分,英语70分. 姓名:李四,数学92分,物理98分,英语8 ...

  2. java IO流详解及特性

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  3. JAVA IO流(韩顺平)

    目录 一.文件 1.1 什么是文件 1.2 文件流 二.常用的文件操作 2.1 创建文件对象相关构造器和方法 2.1.1 代码实现 2.2 获取文件的相关信息 2.2.1 代码实现 2.2.2 相对路 ...

  4. Java IO流详尽解析

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  5. Java IO流学习总结四:缓冲流-BufferedReader、BufferedWriter

    Java IO流学习总结四:缓冲流-BufferedReader.BufferedWriter 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/det ...

  6. Java IO流学习总结七:Commons IO 2.5-FileUtils

    Java IO流学习总结七:Commons IO 2.5-FileUtils 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/5497 ...

  7. Java IO流学习总结六:ByteArrayInputStream、ByteArrayOutputStream

    Java IO流学习总结六:ByteArrayInputStream.ByteArrayOutputStream 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/ar ...

  8. Java IO流学习总结二:File

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/54581478 本文出自[赵彦军的博客] Java IO流学习总结一:输入输出流 J ...

  9. java io 流选择题_java Io流面试题和选择题

    Java对象的序列化指将一个java对象写入OI流中,与此对应的是,对象的反序列化则从IO流中恢复该java对象.下面就由学习啦小编为大家介绍一下java Io流面试题和选择题的文章,欢迎阅读. ja ...

最新文章

  1. Pycharm 建立工程,包含多个工程目录
  2. springboot(七):springboot+mybatis多数据源最简解决方案
  3. 数据结构(Data structures)(二):结构体指针
  4. LeetCode 443. 压缩字符串(双指针)
  5. 五年,时间告诉我只有自己强大才是真的强大!
  6. 贪婪算法在解决哈夫曼树及编码问题中的应用
  7. 目标检测排行榜_3D领域重大突破!大华股份人工智能取得KITTI Object 3D车辆检测排行榜第一名...
  8. 【Python成长之路】机器学习:10+分类算法汇总学习
  9. MATLAB二维数组的创建与元素提取
  10. SpringBoot-技术专区-详细打印启动时异常堆栈信息
  11. Oracle DML封锁机制研究
  12. BZOJ1036[ZJOI2008] 树的统计
  13. 大型网站技术架构 读书笔记2 核心架构要素
  14. 腾讯的天天快报凭什么想挑战今日头条?
  15. omnet++tictoc2案例解析
  16. 如何根据小米12手机电池信息计算充电时间
  17. excel按分数分等级
  18. Quartus II工具1——signaltap
  19. wireshark的usb抓包分析 2 - 分析数据
  20. python列表lambda表达式排序sort(key=lambda x:x[1])

热门文章

  1. 403Forbidden错误的原因和解决方法
  2. [解决方法] 如何将训练过程保存为视频
  3. 外出住酒店,要先烧水浇马桶?对了,还有五件事要注意,别忘了
  4. 猫群算法matlab实现,猫群算法仿生计算在图像聚类分析中的应用
  5. java后端获取前端请求参数
  6. 微博(MicroBlog)
  7. Go微服务实战1:为什么是go
  8. 离职工资少发2000,该怎么维权?|智测优聘总结
  9. 分享10个珍藏很久的网站,我是真的舍不得啊!
  10. 元月元日是哪一天_下元节是哪一天,几月几日