PipedOutputStream 和 PipedInputStream

来源:互联网 发布:动态ppt软件 编辑:程序博客网 时间:2024/06/14 06:35
PipedOutputStream and PipedInputStream
Threads must often communicate. One approach involves using shared variables. Another
approach involves using piped streams via the PipedOutputStream and PipedInputStream classes.
The PipedOutputStream class lets a sending thread write a stream of bytes to an instance of the
PipedInputStream class, which a receiving thread uses to subsequently read those bytes.
Caution Attempting to use a PipedOutputStream object and a PipedInputStream object from a single

thread is not recommended because it might deadlock the thread.

线程必须经常通信。一个方法涉及使用若离变量。另一个方法涉及通过PipedOutputStream和 PipedInputStream 类使用管道流。

PipedOutputStream 让发送线程写一个字节流到PipedInputStream 类的一个实例,接收线程使用它来在后来读这些字节。

警告 不提倡从单一线程尝试使用PipedOutputStream 对象和PipedInputStream 对象,因为它可能死锁该线程。

PipedOutputStream declares a pair of constructors for creating piped output streams:

 PipedOutputStream() creates a piped output stream that’s not yet connected to
a piped input stream. It must be connected to a piped input stream, either by
the receiver or the sender, before being used.
 PipedOutputStream(PipedInputStream dest) creates a piped output stream
that’s connected to piped input stream dest. Bytes written to the piped output
stream can be read from dest. This constructor throws IOException when an
I/O error occurs.
PipedOutputStream declares a void connect(PipedInputStream dest) method that connects this
piped output stream to dest. This method throws IOException when this piped output stream is
already connected to another piped input stream.
PipedInputStream declares four constructors for creating piped input streams:
 PipedInputStream() creates a piped input stream that’s not yet connected to
a piped output stream. It must be connected to a piped output stream before
being used.
 PipedInputStream(int pipeSize) creates a piped input stream that’s not yet
connected to a piped output stream and uses pipeSize to size the piped input
stream’s buffer. It must be connected to a piped output stream before being
used. This constructor throws IllegalArgumentException when pipeSize is less

than or equal to 0.

 PipedInputStream(PipedOutputStream src) creates a piped input stream that’s
connected to piped output stream src. Bytes written to src can be read from
this piped input stream. This constructor throws IOException when an I/O error
occurs.
 PipedInputStream(PipedOutputStream src, int pipeSize) creates a piped
input stream that’s connected to piped output stream src and uses pipeSize
to size the piped input stream’s buffer. Bytes written to src can be read from
this piped input stream. This constructor throws IOException when an I/O error
occurs and IllegalArgumentException when pipeSize is less than or equal to 0.
PipedInputStream declares a void connect(PipedOutputStream src) method that connects this
piped input stream to src. This method throws IOException when this piped input stream is already
connected to another piped output stream.


The easiest way to create a pair of piped streams is in the same thread and in either order. For
example, you can first create the piped output stream.
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
Alternatively, you can first create the piped input stream.
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream(pis);
You can leave both streams unconnected and later connect them to each other using the
appropriate piped stream’s connect() method, as follows:
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream();
// ...
pos.connect(pis);
Listing 11-12 presents a PipedStreamsDemo application whose sender thread streams a sequence of
randomly generated byte integers to a receiver thread, which outputs this sequence.
Listing 11-12. Piping Randomly Generated Bytes from a Sender Thread to a Receiver Thread

清单11-12. 用管道输送随机产生的字节从发送线程到接收线程

import java.io.IOException;

import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipedStreamsDemo
{
public static void main(String[] args) throws IOException
{
final PipedOutputStream pos = new PipedOutputStream();
final PipedInputStream pis = new PipedInputStream(pos);

Runnable senderTask = new Runnable()


{
final static int LIMIT = 10;
@Override
public void run()
{
try
{
for (int i = 0 ; i < LIMIT; i++)
pos.write((byte) (Math.random() * 256));
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
finally
{
try
{
pos.close();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
};
Runnable receiverTask = new Runnable()
{
@Override
public void run()
{
try
{
int b;
while ((b = pis.read()) != -1)
System.out.println(b);
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
finally
{
try
{
pis.close();
}

catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
};
Thread sender = new Thread(senderTask);
Thread receiver = new Thread(receiverTask);
sender.start();
receiver.start();
}
}
Listing 11-12’s main() method creates piped output and piped input streams that will be used by
the senderTask thread to communicate a sequence of randomly generated byte integers and by the
receiverTask thread to receive this sequence.
The sender task’s run() method explicitly closes its pipe stream when it finishes sending the data.
If it didn’t do this, an IOException instance with a “write end dead” message would be thrown when
the receiver thread invoked read() for the final time (which would otherwise return -1 to indicate
end of stream). For more information on this message, check out Daniel Ferber’s “Whats this?
IOException: Write end dead” blog post (http://techtavern.wordpress.com/2008/07/16/whats-
this-ioexception-write-end-dead/).
Compile Listing 11-12 (javac PipedStreamsDemo.java) and run this application (java
PipedStreamsDemo). You’ll discover output similar to the following:
93
23
125
50
126
131
210
29
150
91

0 0