---------------------- android培训、java培训、期待与您交流! ----------------------
7.管道
java.nio.channels包中含有一个名为Pipe(管道)的类,广义上讲,管道就是一个用来在两个实体之间单向传输数据的导管,管道通常被用来连接一个进程的输出和另一个进程的输入。Pipe类实现一个管道范例,不过它所创建的管道是进程内(在Java虚拟机进程内部)而非进程间使用的。
管道由一对通道组成:一个可写入的 sink 通道和一个可读取的 source 通道。一旦将某些字节写入接收器通道,就可以按照与写入时完全相同的顺序从源通道中读取这些字节。
Pipe实例是通过调用不带参数的Pipe.open( )工厂方法来创建的。Pipe类定义了两个嵌套的通
道类来实现管路。这两个类是Pipe.SourceChannel(管道负责读的一端)和Pipe.SinkChannel(管
负责写的一端)。这两个通道实例是在Pipe对象创建的同时被创建的,可以通过在Pipe对象上别调用 source( )和 sink( )方法来取回。此类继承自Object,本身只有以上提到的3个方法。
管道示例:
public class PipeTest {
public static void main(String[] argv) throws Exception {
WritableByteChannel out = Channels.newChannel(System.out);
ReadableByteChannel readableChannel = startWorker(10);
ByteBuffer buffer = ByteBuffer.allocate(100);
while (readableChannel.read(buffer) >= 0) {
buffer.flip();
synchronized (PipeTest.class) {
System.out.print("从管道读取的数据:");
out.write(buffer);
}
buffer.clear();
}
}
//启动一个线程,线程不断向通道中写入数据。并返回一个读通道
private static ReadableByteChannel startWorker(int reps)
throws Exception {
Pipe pipe = Pipe.open();
Worker worker = new Worker(pipe.sink(), reps);
worker.start();
return (pipe.source());
}
private static class Worker extends Thread {
WritableByteChannel channel;
private int reps;
Worker(WritableByteChannel channel, int reps) {
this.channel = channel;
this.reps = reps;
}
public void run() {
ByteBuffer buffer = ByteBuffer.allocate(100);
try {
for (int i = 0; i < this.reps; i++) {
doSomeWork(buffer);
while (channel.write(buffer) > 0) {
}
}
this.channel.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private String[] products = { "No good deed goes unpunished",
"To be, or what?", "No matter where you go, there you are",
"Just say \"Yo\"", "My karma ran over my dogma" };
private Random rand = new Random();
//随机得到一个字符串,并将它写入传入的buffer中,并准备好读取。
private void doSomeWork(ByteBuffer buffer) {
int product = rand.nextInt(products.length);
buffer.clear();
synchronized (PipeTest.class) {
System.out.println("写入管道数据:"+products[product]);
buffer.put(products[product].getBytes());
buffer.put("\r\n".getBytes());
}
buffer.flip();
}
}
}
8.通道工具类
工具类java.nio.channels.Channels定义了几种静态的工厂方法以使通道可以更加容易地同流和读写器互联。方法摘要如下:
static ReadableByteChannel newChannel(InputStream in)
static WritableByteChannel newChannel(OutputStream out)
以上两个方法通过给定流构造相应通道, 不对所得的信道进行缓冲,只是将其 I/O 操作重
定向到给定的流。关闭流会依次导致信道被关闭。
static InputStream newInputStream(ReadableByteChannel ch)
static OutputStream newOutputStream(WritableByteChannel ch)
以上两个方法通过给定通道构造相应流,如果在底层信道处于非阻塞模式的同时调用所得流
的 read 或write方法,则会抛出 IllegalBlockingModeException。不对该流进行缓冲,并
且它不支持 mark 或 reset 方法。多个并发线程访问该流是安全的。关闭流依次会导致信
道被关闭。
static Reader newReader(ReadableByteChannel ch, CharsetDecoder dec, int minBufferCap)
构造一个 reader,它用给定的解码器对取自给定信道的字节进行解码。 所得的流将包含一
个内部输入缓冲区,其大小至少为 minBufferCap 个字节。该流的 read 方法会根据需要填
充该缓冲区,方法是从底层信道读取字节;如果要读取字节时该信道处于非阻塞模式,则抛
出 IllegalBlockingModeException。不支持 mark 或 reset 方法。关闭流依次会导致信道
被关闭。 如果minBufferCap使用取决于实现的默认容量,则为 -1 。
static Reader newReader(ReadableByteChannel ch, String csName)
该方法等价于Channels.newReader(ch, Charset.forName(csName).newDecoder(), -1);
static Writer newWriter(WritableByteChannel ch, CharsetEncoder enc, int minBufferCap)
所得的流将包含一个内部输出缓冲区,其大小至少为 minBufferCap 字节。该流的 write
方法会根据需要刷新该缓冲区,方法是向底层信道写入字节;如果要写入字节时该信道处于
非阻塞模式,则抛出 IllegalBlockingModeException。不另外对所得的流进行缓冲。关闭
流依次会导致信道被关闭。 minBufferCap意义同上。
static Writer newWriter(WritableByteChannel ch, String csName)
等价于Channels.newWriter(ch, Charset.forName(csName).newEncoder(),-1);
关于字符集以及字符集转码的知识将在后面详细讨论。
---------------------- android培训、java培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net/heima