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

15 篇文章 0 订阅
12 篇文章 0 订阅

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);
    }
  }
}

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

读时为空或者写时为满


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值