File I/O source code--Pipe 相关方法阅读
来源:互联网 发布:水果连连看软件 编辑:程序博客网 时间:2024/06/10 10:38
在java I/O把Inter-Thread Communication(线程之间的访问)称之为Pipe(管道),所以我们在使用PipedInputStream、PipedOutputStream、PipedWriter、PipedReader的时候都是和线程结合着使用,这里我们介绍一下PipedWriter和PipedReader相关方法,例子:
import java.io.IOException;import java.io.PipedReader;import java.io.PipedWriter;public class PipeExample { public static void main(String[] args) throws IOException { final PipedWriter writer = new PipedWriter(); final PipedReader reader = new PipedReader(writer); Thread thread3 = new Thread(new Runnable() {@Overridepublic void run() {try {writer.write("Hello piped!");writer.close();} catch (IOException e) {e.printStackTrace();}}}); Thread thread4 = new Thread(new Runnable() {@Overridepublic void run() {try {int data = reader.read();while(data != -1) {System.out.println((char)data);data = reader.read();}reader.close();} catch (IOException e) {e.printStackTrace();}}}); thread3.start(); thread4.start(); }}
之所以叫管道,就是需要互联互通,我们通过例子代码中的构造方法(PipedReader reader = new PipedReader(writer))也可以看出来:
/** * Creates a <code>PipedReader</code> so * that it is connected to the piped writer * <code>src</code>. Data written to <code>src</code> * will then be available as input from this stream. * * @param src the stream to connect to. * @exception IOException if an I/O error occurs. */ public PipedReader(PipedWriter src) throws IOException {this(src, DEFAULT_PIPE_SIZE); }
当新建一个PipedReader对象的同时,会用到一个已经创建好的PipedWriter对象,它的目的是为了给PipedWriter类中的PipedReader sink变量赋值:
package java.io;/** * Piped character-output streams. * * @version %I%, %E% * @authorMark Reinhold * @sinceJDK1.1 */public class PipedWriter extends Writer { /* REMIND: identification of the read and write sides needs to be more sophisticated. Either using thread groups (but what about pipes within a thread?) or using finalization (but it may be a long time until the next GC). */ private PipedReader sink;
那么它是怎样给PipedWriter类中的PipedReader变量sink赋值呢,我们往下看:
/** * Creates a <code>PipedReader</code> so that it is connected * to the piped writer <code>src</code> and uses the specified * pipe size for the pipe's buffer. Data written to <code>src</code> * will then be available as input from this stream. * @param src the stream to connect to. * @param pipeSize the size of the pipe's buffer. * @exception IOException if an I/O error occurs. * @exception IllegalArgumentException if <code>pipeSize <= 0</code>. * @since 1.6 */ public PipedReader(PipedWriter src, int pipeSize) throws IOException {initPipe(pipeSize);connect(src); }
private void initPipe(int pipeSize) {if (pipeSize <= 0) { throw new IllegalArgumentException("Pipe size <= 0");}buffer = new char[pipeSize]; }
这里我们可以看到变量全局变量protected byte buffer[];这个数组就是用来存放我们需要读取流中的数据,等会我们会来介绍这个流中的数据是什么时候给赋值的。
/** * Causes this piped reader to be connected * to the piped writer <code>src</code>. * If this object is already connected to some * other piped writer, an <code>IOException</code> * is thrown. * <p> * If <code>src</code> is an * unconnected piped writer and <code>snk</code> * is an unconnected piped reader, they * may be connected by either the call: * <p> * <pre><code>snk.connect(src)</code> </pre> * <p> * or the call: * <p> * <pre><code>src.connect(snk)</code> </pre> * <p> * The two * calls have the same effect. * * @param src The piped writer to connect to. * @exception IOException if an I/O error occurs. */ public void connect(PipedWriter src) throws IOException {src.connect(this); }
/** * Connects this piped writer to a receiver. If this object * is already connected to some other piped reader, an * <code>IOException</code> is thrown. * <p> * If <code>snk</code> is an unconnected piped reader and * <code>src</code> is an unconnected piped writer, they may * be connected by either the call: * <blockquote><pre> * src.connect(snk)</pre></blockquote> * or the call: * <blockquote><pre> * snk.connect(src)</pre></blockquote> * The two calls have the same effect. * * @param snk the piped reader to connect to. * @exception IOException if an I/O error occurs. */ 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; }
到这里我们可以看到当final PipedReader reader = new PipedReader(writer);构造一个PipedReader对象的时候,它做到了两点:
•初始化PipedReader中的数组变量buffer[];
•将PipedReader对象赋值给PipedWriter类中的PipedReader变量sink
我们需要注意的是connect(PipedReader snk)方法加了一个synchronized变量,那么这个变量的意思是什么呢?
我们再来看下writer.write("Hello piped!");源码都做了些什么:
/** * Writes a string. * * @param str * String to be written * * @throws IOException * If an I/O error occurs */ public void write(String str) throws IOException {write(str, 0, str.length()); }
/** * Writes <code>len</code> characters from the specified character array * starting at offset <code>off</code> to this piped output stream. * This method blocks until all the characters are written to the output * stream. * If a thread was reading data characters from the connected piped input * stream, but the thread is no longer alive, then an * <code>IOException</code> is thrown. * * @param cbuf the data. * @param off the start offset in the data. * @param len the number of characters to write. * @exception IOException if the pipe is *<a href=PipedOutputStream.html#BROKEN> <code>broken</code></a>, *{@link #connect(java.io.PipedReader) unconnected}, closed *or an I/O error occurs. */ public void write(char cbuf[], int off, int len) throws IOException { if (sink == null) { throw new IOException("Pipe not connected"); } else if ((off | len | (off + len) | (cbuf.length - (off + len))) < 0) { throw new IndexOutOfBoundsException();}sink.receive(cbuf, off, len); }
这里我们要好好看下sink.receive(cbuf, off, len);方法。当我们写数据的同时,其实就把数据写入到了PipedReader数组buffer[]中了:
/** * Receives data into an array of characters. This method will * block until some input is available. */ synchronized void receive(char c[], int off, int len) throws IOException {while (--len >= 0) { receive(c[off++]);} }
/** * Receives a char of data. This method will block if no input is * available. */ synchronized void receive(int c) throws IOException { if (!connected) { throw new IOException("Pipe not connected"); } else if (closedByWriter || closedByReader) { throw new IOException("Pipe closed");} else if (readSide != null && !readSide.isAlive()) { throw new IOException("Read end dead"); }writeSide = Thread.currentThread();while (in == out) { if ((readSide != null) && !readSide.isAlive()) {throw new IOException("Pipe broken"); } /* full: kick any waiting readers */ notifyAll(); try { wait(1000); } catch (InterruptedException ex) {throw new java.io.InterruptedIOException(); }}if (in < 0) { in = 0; out = 0;}buffer[in++] = (char) c;if (in >= buffer.length) { in = 0;} }
0 0
- File I/O source code--Pipe 相关方法阅读
- File I/O source code--新建文件 相关方法阅读
- File I/O source code--读取文件 相关方法阅读
- File I/O source code--写入文件 相关方法阅读
- ArrayList source code相关方法阅读
- bmp file dump source code(I write)
- Python 文件I/O和File方法
- HashMap source code 阅读
- linux file I/O
- Linux file I/O
- C++ File I/O
- FILE I/O
- Multithreaded File I/O
- FILE I/O
- Python File I/O
- I/O 1.0 File
- File I/O
- C++ File I/O
- Android socket 编程 实现消息推送(二)
- apache架构
- 第十六周 项目二--用指针玩字符串(2.2.2去除字符串中特定字符--指针作形参)
- 算法与数据结构面试题(7)-链表“香蕉”问题
- hibernate调用删除和保存函数出错
- File I/O source code--Pipe 相关方法阅读
- python编译成windows exe可执行文件
- 第十六周项目二用指针玩字符串任务二:去除字符串中的空格(用数组名作形参)
- cocos2d js Pageview的用法
- 哈夫曼编码
- 复数计算
- Struts2(XWork)拦截器的功能介绍:
- Leet code Maximum Gap
- 黑马程序员——Foundation框架——常用结构体(NSRange、NSPoint等)