Java I/O全文摘要(九)过滤流,内存流

来源:互联网 发布:网络断网监控 编辑:程序博客网 时间:2024/04/28 05:31

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 InputStreampublic class PipedOutputStream extends OutputStream

他们都具有无参和依赖对方的构造方法:

public PipedOutputStream(PipedInputStream sink) throws IOExceptionpublic PipedOutputStream( )

PipedOutputStream pout = new PipedOutputStream( );PipedInputStream  pin  = new PipedInputStream(pout);

你可以再同一个线程中使用他们。

如果你在最初没有建立两者的联系,可以使用

pin.connect(pout);
的方式来建立两者的连接。


除此之外,管道流提供了4个字段和1个方法:

protected static final int PIPE_SIZEprotected byte[] bufferprotected int inprotected int outprotected 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);    }  }}

有两个地方会可能出现阻塞:

读时为空或者写时为满


0 0