1 内存流
之前的章节中,讲述了如何从Java程序的一个数据源移动数据到另一个数据源。流还可以从Java程序的一个部分移动数据到另一个部分。
本章讲解下面这些流:
Sequence stream,Byte array stream, Piped stream
Sequence stream:将多个流合成单一流。
Byte array stream:将输出储存在字节数组中或者从字节数组中读出数据。
2 序列输入流
可将多个流合成一个流:
合并两个流:
public SequenceInputStream(InputStream in1, InputStream in2)
合并一组流:
public SequenceInputStream(Enumeration<? extends InputStream> e)
之所以是Enumeration是因为这个在1.0时代就有了,在5.0时加上了泛型限制。
样例:你可以创建两个流,然后将其放入序列流,这样,你使用起来就像一个流。
URL u1 = new URL("http://www.yahoo.com/");
URL u2 = new URL("http://www.google.com");
SequenceInputStream sin = new SequenceInputStream(
u1.openStream(), u2.openStream( ));
3 字节数组输入流
构造方法:
public ByteArrayInputStream(byte[] buffer)
public ByteArrayInputStream(byte[] buffer, int offset, int length)
从byte[]中读取数据,然后生成流。
4 字节数组输出流
构造方法:
public ByteArrayOutputStream( )
public ByteArrayOutputStream(int size)
默认为32byte.
这个是将内存中的数据写出去。但是默认情况下,并没有写出去的地方,为了解决这个问题:
使用本身的writeTo( )方法:
public void writeTo(OutputStream out) throws IOException
例如,你可以先使用过滤流进行装饰:
ByteArrayOutputStream bout = new ByteArrayOutputStream(howMany*4);
DataOutputStream dout = new DataOutputStream(bout);
然后使用writeTo方法,指定输出:
FileOutputStream fout = new FileOutputStream("fibonacci.dat");
try {
bout.writeTo(fout);
fout.flush( );
}
finally {
fout.close( );
}
5 使用管道流在线程中通信
java.io.PipedInputStream 和java.io.PipedOutputStream提供了一些便利的方法在线程直接进行数据的搬运操作。
它的构造方法如下:
public class PipedInputStream extends InputStream
public class PipedOutputStream extends OutputStream
他们都具有无参和依赖对方的构造方法:
public PipedOutputStream(PipedInputStream sink) throws IOException public PipedOutputStream( )
和
PipedOutputStream pout = new PipedOutputStream( ); PipedInputStream pin = new PipedInputStream(pout);
你可以再同一个线程中使用他们。
如果你在最初没有建立两者的联系,可以使用
pin.connect(pout);的方式来建立两者的连接。
除此之外,管道流提供了4个字段和1个方法:
protected static final int PIPE_SIZE
protected byte[] buffer
protected int in
protected int out
protected void receive(int b) throws IOException
in,out 是记录位置的。
下面是一个例子:
写线程写入数据
import java.io.*;
public class FibonacciProducer extends Thread {
private DataOutputStream theOutput;
private int howMany;
public FibonacciProducer(OutputStream out, int howMany) {
theOutput = new DataOutputStream(out);
this.howMany = howMany;
}
public void run( ) {
try {
int f1 = 1;
int f2 = 1;
theOutput.writeInt(f1);
theOutput.writeInt(f2);
// Now calculate the rest.
for (int i = 2; i < howMany; i++) {
int temp = f2;
f2 = f2 + f1;
f1 = temp;
if (f2 < 0) { // overflow
break;
}
theOutput.writeInt(f2);
}
}
catch (IOException ex) { System.err.println(ex); }
}
}
读线程循环的读出来
import java.io.*;
public class FibonacciConsumer extends Thread {
private DataInputStream theInput;
public FibonacciConsumer(InputStream in) {
theInput = new DataInputStream(in);
}
public void run( ) {
try {
while (true) {
System.out.println(theInput.readInt( ));
}
}
catch (IOException ex) {
if (ex.getMessage( ).equals("Pipe broken")) {
// normal termination
return;
}
System.err.println(ex);
}
}
}
有两个地方会可能出现阻塞:
读时为空或者写时为满