正文

本篇讲述的是Java IO中的Reader类和Writer类。跟之前讲述的InputStream和OutputStream一样为IO流中的抽象父类之一,不过Reader和Writer的操作对象不再是字节而是字符了。下面也不多说,贴上源码来加深我们的理解。

Reader.java

package java.io;public abstract class Reader implements Readable, Closeable {/*** 声明一个Object对象,为后续方法进行同步操作时,提供同步锁*/protected Object lock;/*** 一个不带参的构造方法,并将锁对象lock初始化为当前类*/protected Reader() {this.lock = this;}/***一个带一个参数的构造方法,传入一个Object对象,对传入参数进行安全监测后,将传入参数赋值给锁对象lock*/protected Reader(Object lock) {if (lock == null) {throw new NullPointerException();}this.lock = lock;}/*** 一个带一个参数的read方法,传入的参数为一个字符缓冲区对象,从流中读取字符数据放置与字符缓冲区中,最终返回实际存储到字符缓冲区的字符的数量*/public int read(java.nio.CharBuffer target) throws IOException {//返回字符缓冲区中可以使用的元素数量,将其作为临时字符数组的长度int len = target.remaining();//创建一个字符数组,用于读取流中的数据char[] cbuf = new char[len];int n = read(cbuf, 0, len);//读取数据后,将字符数组中的数据全部置于字符缓冲区中if (n > 0)target.put(cbuf, 0, n);return n;}/***一个不带参数的read方法,每次读取一个字符,如果没有成功读取到字符数据返回-1,否则返回读取到的字符*/public int read() throws IOException {char cb[] = new char[1];if (read(cb, 0, 1) == -1)return -1;elsereturn cb[0];}/*** 一个带一个参数的read方法,传入的参数为一个字符数组,从流中读取数据,并将数据存放入传入的字符数组中,最终返回成功读取到的字符数量*/public int read(char cbuf[]) throws IOException {return read(cbuf, 0, cbuf.length);}/***一个带三个参数的read方法,该方法为抽象方法,第一个参数为一个字符数组,第二个参数为数据存储开始的位置,第三个参数为数据存储使用的长度*/abstract public int read(char cbuf[], int off, int len) throws IOException;/***声明了一个静态常量,maxSkipBufferSize,将其赋值为8192,该值表明了最多能跳过的字符数*/private static final int maxSkipBufferSize = 8192;/** *声明了一个字符数组,该数组用于跳过阅读*/private char skipBuffer[] = null;/*** 一个带一个参数的skip方法,参数为long型,表明要跳过的长度*/public long skip(long n) throws IOException {//对传入参数进行安全监测,如果小于0,则抛出异常if (n < 0L)throw new IllegalArgumentException("skip value is negative");//确定跳过的字符数量,如果n没有超过最大限定的值,则跳过n个长度,如果大于最大值,则跳过最大值的长度(maxSkipBufferSize)int nn = (int) Math.min(n, maxSkipBufferSize);//如果skipbuffer为空或者其容量不足以满足跳跃的长度,则新建一个skipBuffersynchronized (lock) {if ((skipBuffer == null) || (skipBuffer.length < nn))skipBuffer = new char[nn];long r = n;//根据需要跳过的长度来进行读取,最终返回实际跳过的字符数量while (r > 0) {int nc = read(skipBuffer, 0, (int)Math.min(r, nn));if (nc == -1)break;r -= nc;}return n - r;}}/*** 检测当前流是否可读,此处永远返回false*/public boolean ready() throws IOException {return false;}/*** 检测当前流是否支持标记功能,此处永远返回false*/public boolean markSupported() {return false;}/***一个带一个参数的mark方法,传入的参数为标记的位置,用于在流中进行标记,一般与reset方法一起使用*/public void mark(int readAheadLimit) throws IOException {throw new IOException("mark() not supported");}/***一个不带参数的reset方法,将流的读取位置重置到被mark方法标记的位置*/public void reset() throws IOException {throw new IOException("reset() not supported");}/*** close方法用于关闭流,是一个抽象方法*/abstract public void close() throws IOException;}

Writer.java

package java.io;public abstract class Writer implements Appendable, Closeable, Flushable {/*** 声明了一个字符数组,用于存放需要写出的数据*/private char[] writeBuffer;/*** 定义了静态常量值 WRITE_BUFFER_SIZE,该值为存放写出数据的字符数组的初始容量,初始容量为1024*/private static final int WRITE_BUFFER_SIZE = 1024;/*** 声明一个Object对象,为后续方法进行同步操作时,提供同步锁*/protected Object lock;/*** 一个不带参的构造方法,并将锁对象lock初始化为当前类*/protected Writer() {this.lock = this;}/*** 一个带有一个参数的Writer对象,传入的参数为一个Object对象,并将该值赋值给锁对象lock*/protected Writer(Object lock) {if (lock == null) {throw new NullPointerException();}this.lock = lock;}/*** 带有一个参数的write方法,传入的是一个字符的int型值,每次写出一个字符*/public void write(int c) throws IOException {synchronized (lock) {if (writeBuffer == null){writeBuffer = new char[WRITE_BUFFER_SIZE];}writeBuffer[0] = (char) c;write(writeBuffer, 0, 1);}}/*** 带有一个参数的write方法,传入的是一个字符型数组,将传入的数组中的内容一次写出*/public void write(char cbuf[]) throws IOException {write(cbuf, 0, cbuf.length);}/*** 一个带有三个参数的write方法,第一个参数为一个字符型数组,其中存放着需要写出的数据,第二个参数为开始写出的位置,第三个参数为需要写出的长度*该方法为抽象方法*/abstract public void write(char cbuf[], int off, int len) throws IOException;/*** 一个带有一个参数的write方法,该参数为一个要写出的字符串数据*/public void write(String str) throws IOException {write(str, 0, str.length());}/*** 一个带有三个参数的write方法,第一个参数为要写出的字符串数据,第二个参数为开始写出的位置,第三个参数为需要写出的长度*/public void write(String str, int off, int len) throws IOException {synchronized (lock) {//声明了一个字符数组char cbuf[];//如果writeBuffer没有创建过,则创建。如果写出长度<小于定义的初始容量,则wirteBuffer初始化容量为1024,如果大于,则用长度初始化其容量if (len <= WRITE_BUFFER_SIZE) {if (writeBuffer == null) {writeBuffer = new char[WRITE_BUFFER_SIZE];}cbuf = writeBuffer;} else {    // Don't permanently allocate very large buffers.cbuf = new char[len];}//将需要写出的字符串转化为字符数组,写出str.getChars(off, (off + len), cbuf, 0);write(cbuf, 0, len);}}/***一个带有一个参数的append方法,传入的参数为一个CharSequence类型的数据,经过安全监测后,将其转化为String型写出,最终返回当前Writer对象*/public Writer append(CharSequence csq) throws IOException {if (csq == null)write("null");elsewrite(csq.toString());return this;}/*** 一个带有三个参数的append方法,第一个参数是一个CharSequence类型的数据,第二个参数为要开始添加的位置,第三个参数为结束的位置*/public Writer append(CharSequence csq, int start, int end) throws IOException {//对传入的csq先进行安全监测,通过后,根据起始位置和结束位置截取CharSequence数据,然后写出,最终返回当前Writer对象CharSequence cs = (csq == null ? "null" : csq);write(cs.subSequence(start, end).toString());return this;}/*** 一个带有一个参数的append方法,传入的参数为一个char型的数据,写入一个字符,最终返回当前Writer对象*/public Writer append(char c) throws IOException {write(c);return this;}/***一个抽象方法flush,该方法用于将缓存中的写入数据写出值目的处*/abstract public void flush() throws IOException;/*** 关闭流*/abstract public void close() throws IOException;}

经过上面的源码可以看出,Reader/Writer和InputStream/OutputStream是十分相似的。当然也有一定的区别,最本质的区别就是前者是对字符进行操作,后者是对字节进行操作。并且两者间有些同名方法关于是否是抽象化方法略有不同。

Java IO 体系(三):Reader与Writer相关推荐

  1. java中io流,Reader和Writer,InputStream和OutputStream,转换流 InputStreamReader 和 OutputStreamWriter

    java中所谓流通俗来讲就是数据源的传输,我们的文件,视屏,对象都可以叫做数据源,io将他们那转换为可以在不同程序中传输的数据,众所周知电脑存储是二进制,而处理时常遇到字节和字符的写入和写出,分别以8 ...

  2. java+io体系结构图_Java IO 体系结构

    Java IO体系结构看似庞大复杂,其实有规律可循,要弄清楚其结构,需要明白两点: 1. 其对称性质:InputStream 与 OutputStream, Reader 与 Writer,他们分别是 ...

  3. Java IO 体系(二): inputstream与outputstream

    Java中文件数据流操作有2个大类:OutputStream/InputStream接口 和 FileWriter/FileReader类 1. OutputStream接口:所有字节输出流的超类 包 ...

  4. Java IO 体系(一): 装饰者模式

    前言. IO中常见的使用方式 DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputSt ...

  5. java io体系_java IO流的体系结构图

    常用字节流字符流 字节流   InputStream                                                                           ...

  6. Java IO体系结构图

    输入流 输出流 InputStream系列是JDK1.0开始的,Reader系列是JDK1.1开始的 字节流中,常用的是FileInputStream和BufferedInputStream 字符流中 ...

  7. Java IO实战操作(三)

    /** * IO管道处理集合 */ public void OutFile() throws FileNotFoundException { /** * 使用PrintStream进行输出 */ Pr ...

  8. Java IO: Reader And Writer

    转载自  Java IO: Reader And Writer 译文链接 作者: Jakob Jenkov  译者: 李璟(jlee381344197@gmail.com) Java IO的Reade ...

  9. Java IO: Reader和Writer

    转载自   Java IO: Reader和Writer 作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) Reader 原文链接 Reader是Jav ...

最新文章

  1. 五千万美元注资孵化器,ETC能实现绝地反击吗?
  2. ffmpeg转码速度控制方法
  3. 基础概念总结(spring security、Quartz、JUnit测试)
  4. Android多线程之同步锁的使用
  5. 爬虫必须得会的Web知识
  6. 管理者必看!深度剖析BI与数据仓库,企业能否成功转型就看它
  7. 关闭word_记一次毕设消失事件始末,及mac+word文档消失恢复方法汇总
  8. oracle秒级查询,oracle 中查询超过10秒以上的sql语句(性能优化)
  9. 单元测试 代码里面都绝对路径怎么处理_python基础之包,异常处理
  10. qt如何在TetxEdit设置背景色(可以设置行或列)
  11. 简单工厂模式、工厂模式以及抽象工厂模式(具体)
  12. length()、size()、sizeof()三者的区别
  13. linux如何每30分钟执行指令,CentOS7设置定时任务 每隔30分钟执行一次命令
  14. 如何给PDF文件加密和解密?
  15. 2008中国IC十佳(七):深圳芯邦冲刺创业板
  16. firefox 浏览器证书问题
  17. 组合博弈 -- 三大基本博弈
  18. 基于动作捕捉的踝关节动力矫形器外骨骼开发
  19. edge如何导入html文件收藏夹,win10系统edge浏览器收藏夹导入/导出的操作方法
  20. 虚拟磁盘服务错误: 卷大小太大。

热门文章

  1. php 字体问题,php – Scraping上的字体或Unicode问题[复制]
  2. powershell查看mysql密码_使用Windows PowerShell从数据库导入用户
  3. 如何查找历史线程阻塞原因_java并发编程-线程状态,线程阻塞方式,阻塞中的线程如何终止?...
  4. python和c运行速度的对比实验_Python中单线程、多线程和多进程的效率对比实验...
  5. python中堆排序_python堆排序,详细过程图和讲解,这样做小白都会
  6. 通用窗口类 Inventory Pro 2.1.2 Demo1(下)
  7. 最喜欢的 jQuery 插件
  8. 创建一个Table View
  9. 【转】java提高篇(十)-----详解匿名内部类
  10. 用Lambda武装你的Java: 集合转换