天天看点

从JDK源码看Writer

Writer 是一个用于写字符流的抽象类,它将一些相通的写相关操作抽象到此类,方便各种写操作类的实现。一般来说子类只需要实现它的 write、flush 、close 等三个方法,但如果有需要还可以重写 Writer 提供的公共方法。

JDK 在 Writer 的基础上实现了很多有用的 xxxWriter ,包括 BufferedWriter、CharArrayWriter、FilterWriter、OutputStreamWriter、FileWriter、PipedWriter、StringWriter 和 PrintWriter 等等。

Writer 被定为 public 且 abstract 的类,实现了 Appendable、Closeable 和 Flushable接口。

Appendable 接口表示字符或字符序列可以被 append,接口定义如下:

Closeable 接口表示 Writer 可以被close,接口定义如下:

Flushable 接口表示 Writer 可以被flush,接口定义如下:

writeBuffer 是一个 char[] 类型,表示写缓冲。

WRITE_BUFFER_SIZE 写缓冲的大小。

lock 是 Writer 的锁,用于实现同步。

有两种构造方法,不带参数时则将自己作为锁,而如果传入了某个 Object 对象则将其作为锁。

一共有五个 write 方法,其中有一个抽象的 write 方法,可以看到所有 write 方法最终都会调用这个抽象方法,提供给子类处理逻辑的实现。它传入的三个参数,字符数组cbuf、偏移量off和数组长度。

写入一个 int 类型值时,先通过锁进行同步,再判断 writeBuffer 为 null 则要实例化一个对象,接着将 int 值转成char类型,最后调用抽象 write 方法执行子类逻辑。

写入 char 数组是则直接调用抽象 write 方法。

写入 String 类型数据也有类似的处理,同样是先加锁,再实例化一个 char 数组用于存放写入数据,这里不同的地方在于要根据 String 数据的长度处理,如果小于 WRITE_BUFFER_SIZE 则直接使用 Writer 里面的 writeBuffer 对象,而如果大于 WRITE_BUFFER_SIZE 则需要按照String数据的长度 new 一个 char 数组,但为了节约内存,这个较大的数组使用过后即会被 gc 掉,不必跟着 Writer 的生命周期一直存在。

一共有3个append方法,该方法是 Appendable 接口规定的方法,在实现中其实就是间接调用 write 方法进行写入操作,但不同的是它返回了 this,这样就可以方便地使用 append(“xxx”).append(“yyy”)。

它是一个抽象方法,留给子类实现。此方法用于刷新流,如果 Writer 的缓冲区包含任何字符则马上将其写入目的地。但如果目的地是另外一个流,则继续调用其 flush 方法刷新,所以调用 flush 会刷新 Writer 链的所有缓冲。

此外,如果写入目的地建立在操作系统之上,比如操作系统的文件系统,那么 flush 只保证将缓冲写入操作系统中,而不保证其写入硬盘等物理设备中。

它是一个抽象方法,留给子类实现。此方法用于关闭流,关闭之前要先执行 flush 将缓冲刷入目的地。如果某个流已经关闭了还调用 write 或 flush 方法,则将抛出 IOException 。

以下是广告和相关阅读

========广告时间========

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/74080321">为什么写《Tomcat内核设计剖析》</a>

=========================

相关阅读:

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/73743876">从JDK源码角度看Object</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/78026810">从JDK源码角度看Long</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/77196626">从JDK源码角度看Integer</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/78183273">从JDK源码角度看Float</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/77941129">volatile足以保证数据同步吗</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/72933108">谈谈Java基础数据类型</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/51455094">从JDK源码角度看并发锁的优化</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/51468764">从JDK源码角度看线程的阻塞和唤醒</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/51433204">从JDK源码角度看并发竞争的超时</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/51397266">从JDK源码角度看java并发线程的中断</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/51371416">从JDK源码角度看Java并发的公平性</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/51360228">从JDK源码角度看java并发的原子性如何保证</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/74557125">从JDK源码角度看Byte</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/73350488">从JDK源码角度看Boolean</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/76557578">从JDK源码角度看Short</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/78246035">从JDK源码看System.exit</a>

<a href="http://blog.csdn.net/wangyangzhizhou/article/details/78315757">从JDK源码看关闭钩子</a>

欢迎关注:

从JDK源码看Writer
从JDK源码看Writer