文档章节

Java IO类库之PipedWriter

 老韭菜
发布于 2018/08/15 14:22
字数 1030
阅读 1
收藏 0

一、PipedWriter介绍

    PipedWriter是字符管道输出流,继承自Writer,功能与PipedOutputStream类似,通过与PipedReader组合使用实现类似管道的功能,在多线程环境下,一个线程使用PipedWriter写入数据,通过管道将数据传递到管道另一端的字符输入流内部缓冲区(实际是通过当前字符管道输出流绑定的字符管道输入流对象sink的receive方法将数据存储到字符输入流的内部字符缓冲区实现的),其他线程去读该内部缓冲区的字符数据,实现线程间通信。

二、PipedWriter类成员变量

package java.io;

public class PipedWriter extends Writer {

    /** 管道绑定的字符输入流对象 **/
    private PipedReader sink;

    /* 
     * 当前管道字符输出流的状态,独立于管道另一端字符输入流的状态
     */
    private boolean closed = false;

}

三、PipedWriter源码分析

1 - 构造函数

   /**
    * 构造函数,调用connect为当前对象与指定字符管道输入流对象建立连接
    */
   public PipedWriter(PipedReader snk)  throws IOException {
        connect(snk);
    }

    /**
     * 构造函数,空实现,还没与管道的字符输入流建立连接,在使用之前必须先建立连接无论是管道数据接收端PipedReader还是
     * 还是数据写入端PipedWriter调用connect建立连接
     */
    public PipedWriter() {
    }

    PipedWriter的构造函数逻辑非常简单,两种构造函数一种什么都没做只是创建一个未建立管道连接的对象,另一个构造函数在实例化的同时调用connect创建了与指定字符管道输入流对象的管道连接,之后PipedWriter主要是基于这个指定的管道输入流对象操作管道数据。

2 - void write(int c)方法 - 写入单个字符

    public void write(int c)  throws IOException {
        if (sink == null) {
            throw new IOException("Pipe not connected");
        }
        sink.receive(c);
    }

    方法逻辑很简单就是在开头做了管道绑定的接收端字符管道输入流对象sink的判空,若不为空则调用它的receive方法接收写入的单个字符c,receive的内部方法逻辑可参照上篇PipedReader对于receive方法的解析

3 - 其他成员方法

    /**
     * 为当前管道输出流对象连接指定的管道输入流对象snk,若当前管道输出流之前已经建立与其他字符管道输入流的连接则抛出
     * IOException异常
     */
    public synchronized void connect(PipedReader snk) throws IOException {
        if (snk == null) {
            throw new NullPointerException();
        } else if (sink != null || snk.connected) {
            throw new IOException("Already connected");
        } else if (snk.closedByReader || closed) {
            throw new IOException("Pipe closed");
        }

        sink = snk;
        snk.in = -1;
        snk.out = 0;
        snk.connected = true;
    }


    /**
     * 将指定字符数组cbuf从off位置开始len个字符写入管道绑定的字符管道输入流对象内部缓冲区中
     * 如果一个线程正在读取连接的字符管道输入流内部缓冲区字节数据,这时候当前线程挂掉那么会抛出一个IO异常
     */
    public void write(char cbuf[], int off, int len) throws IOException {
        //管道绑定的字符管道输入流对象为空
        if (sink == null) {
            throw new IOException("Pipe not connected");
        } 
        /** 校验字符数组起始位置参数off **/
        else if ((off | len | (off + len) | (cbuf.length - (off + len))) < 0) {
            throw new IndexOutOfBoundsException();
        }
        //将字符数组数据写入管道绑定的字符输入流内部缓冲区
        sink.receive(cbuf, off, len);
    }

    /**
     * 刷新管道输出流,主要是通过唤醒管道输入流等待读取线程读取数据实现刷新的。
     */
    public synchronized void flush() throws IOException {
        if (sink != null) {
            if (sink.closedByReader || closed) {
                throw new IOException("Pipe closed");
            }
            synchronized (sink) {
                sink.notifyAll();
            }
        }
    }

    /**
     * 关闭当前管道输出流对象,释放与此有关的系统资源,实际是调用绑定的管道输入流对象sink的reveivedLast方法
     * 更新sink管道写入端状态成员变量closedByWriter并唤醒其他等待线程
     */
    public void close()  throws IOException {
        closed = true;
        if (sink != null) {
            sink.receivedLast();
        }
    }

 

© 著作权归作者所有

共有 人打赏支持
粉丝 12
博文 64
码字总数 107681
作品 0
杭州
后端工程师
私信 提问
Java_io体系之PipedWriter、PipedReader

Javaio体系之PipedWriter、PipedReader简介、走进源码及示例——14 这两个类必须配套来使用,一般是用于两个线程之间的通信,想了一下其实就是一个线程往buf数组写,另一个线程从这个buf数组...

z_jordon
2015/04/28
0
0
InputStream和Reader的区别

java.io.Reader 和 java.io.InputStream 组成了Java 输入类。Reader 用于读入16位字符,也就是Unicode 编码的字符;而 InputStream 用于读入 ASCII 字符和二进制数据。 Reader支持16位的Uni...

SibylY
2013/08/14
0
0
Java多线程学习(五)线程间通信知识点补充

系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Ja...

一只蜗牛呀
2018/04/16
0
0
有效选择七个关于 Java 的 JSON 开源类库

有效选择七个关于Java的JSON开源类库 April 4, 2014 By Constantin Marian Alin 翻译:无若 (英语原文:http://www.developer.com/lang/jscript/top-7-open-source-json-binding-providers-......

溪边九节
2014/04/19
12.5K
14
Jython 2.7 alpha1 发布

Jython 2.7 alpha1 发布了,可通过这里 下载. 详情请看 安装指南 Jython 2.7 alpha1 实现了大部分 CPython 2.6 和 2.7 的功能,但还有一些缺失,特别是 bytearray 和 io 系统上目前还没完成。...

oschina
2012/05/17
1K
1

没有更多内容

加载失败,请刷新页面

加载更多

数据库篇多表操作

第1章 多表操作 实际开发中,一个项目通常需要很多张表才能完成。例如:一个商城项目就需要分类表(category)、商品表(products)、订单表(orders)等多张表。且这些表的数据之间存在一定的关系...

stars永恒
8分钟前
0
0
nginx日志自动切割

1.日志配置(Nginx 日志) access.log----记录哪些用户,哪些页面以及用户浏览器,IP等访问信息;error.log------记录服务器错误的日志 #配置日志存储路径:location / {      a...

em_aaron
昨天
1
0
java 反射

基本概念 RTTI,即Run-Time Type Identification,运行时类型识别。RTTI能在运行时就能够自动识别每个编译时已知的类型。   要想理解反射的原理,首先要了解什么是类型信息。Java让我们在运...

细节探索者
昨天
1
0
推荐转载连接

https://www.cnblogs.com/ysocean/p/7409779.html#_label0

小橙子的曼曼
昨天
3
0
雷军亲自打造的套餐了解下:用多少付多少

12月28日消息,小米科技创始人兼CEO雷军微博表示,小米移动任我行套餐方案,原则上就是明明白白消费,用多少付多少,不用不花钱!上网、电话和短信都是一毛钱,上网0.1元/M,电话0.1元/分钟,...

linuxCool
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部