Java IO流之OutputStreamWriter和InputStreamReader分析
简介
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分析相关推荐
- java IO流 练习题 分析成绩单
java IO流 练习题 题目要求: 分析成绩单. 现在有如下格式的成绩单(文本格式)score.txt: 姓名:张三,数学72分,物理67分,英语70分. 姓名:李四,数学92分,物理98分,英语8 ...
- java IO流详解及特性
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- JAVA IO流(韩顺平)
目录 一.文件 1.1 什么是文件 1.2 文件流 二.常用的文件操作 2.1 创建文件对象相关构造器和方法 2.1.1 代码实现 2.2 获取文件的相关信息 2.2.1 代码实现 2.2.2 相对路 ...
- Java IO流详尽解析
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- Java IO流学习总结四:缓冲流-BufferedReader、BufferedWriter
Java IO流学习总结四:缓冲流-BufferedReader.BufferedWriter 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/det ...
- Java IO流学习总结七:Commons IO 2.5-FileUtils
Java IO流学习总结七:Commons IO 2.5-FileUtils 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/5497 ...
- Java IO流学习总结六:ByteArrayInputStream、ByteArrayOutputStream
Java IO流学习总结六:ByteArrayInputStream.ByteArrayOutputStream 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/ar ...
- Java IO流学习总结二:File
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/54581478 本文出自[赵彦军的博客] Java IO流学习总结一:输入输出流 J ...
- java io 流选择题_java Io流面试题和选择题
Java对象的序列化指将一个java对象写入OI流中,与此对应的是,对象的反序列化则从IO流中恢复该java对象.下面就由学习啦小编为大家介绍一下java Io流面试题和选择题的文章,欢迎阅读. ja ...
最新文章
- Pycharm 建立工程,包含多个工程目录
- springboot(七):springboot+mybatis多数据源最简解决方案
- 数据结构(Data structures)(二):结构体指针
- LeetCode 443. 压缩字符串(双指针)
- 五年,时间告诉我只有自己强大才是真的强大!
- 贪婪算法在解决哈夫曼树及编码问题中的应用
- 目标检测排行榜_3D领域重大突破!大华股份人工智能取得KITTI Object 3D车辆检测排行榜第一名...
- 【Python成长之路】机器学习:10+分类算法汇总学习
- MATLAB二维数组的创建与元素提取
- SpringBoot-技术专区-详细打印启动时异常堆栈信息
- Oracle DML封锁机制研究
- BZOJ1036[ZJOI2008] 树的统计
- 大型网站技术架构 读书笔记2 核心架构要素
- 腾讯的天天快报凭什么想挑战今日头条?
- omnet++tictoc2案例解析
- 如何根据小米12手机电池信息计算充电时间
- excel按分数分等级
- Quartus II工具1——signaltap
- wireshark的usb抓包分析 2 - 分析数据
- python列表lambda表达式排序sort(key=lambda x:x[1])