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);
}
}
}
有兩個地方會可能出現阻塞:
讀時爲空或者寫時爲滿