Java IO可以分为两大类,一个是字节流对象,一个是字符流对象。字节流对象读取的是一个一个的字节,即以字节为单位进行读取。而字符流对则是以字符为单位进行读取。一般来说,字符流的效率要高些。但为什么还要有字节流对象呢?
这是因为流对象的表现形式有很多种。如果仅仅是文本数据,则单单用一个字符流对象就可以了。但是很多时候我们操作的是图片、电影、mp3等这样的数据,就只能用字节流对象了。因为字符流对象在操作的过程中会用当前系统指定的编码格式进行编码和解码。所以就不能操作那些非文本数据了。
要想把Java的IO对象全部说完,短时间内是不可能的。也没有必要。那些很常见的一般大家都很熟悉了。也就没必要再重复了。我就介绍几个比较独特,有特定适用环境的流对象吧。
PipedInputStream和PipedOutputStream
PipedInputStream
管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从 PipedInputStream
对象读取,并由其他线程将其写入到相应的PipedOutputStream
。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。如果向连接管道输出流提供数据字节的线程不再存在,则认为该管道已损坏。--------Java文档
PipedOutputStream
可以将管道输出流连接到管道输入流来创建通信管道。管道输出流是管道的发送端。通常,数据由某个线程写入 PipedOutputStream
对象,并由其他线程从连接的PipedInputStream
读取。不建议对这两个对象尝试使用单个线程,因为这样可能会造成该线程死锁。如果某个线程正从连接的管道输入流中读取数据字节,但该线程不再处于活动状态,则该管道被视为处于毁坏状态。-----Java 文档
注意到文档中的一句话,“不建议对这两个对象尝试使用单个线程,因为这样可能会造成该线程死锁。”也就是说应该在多线程环境下使用这两个对象。多线程下的话我们就可以利用它们进行线程间的通信。PipedOutputStream 负责发送信息,PipedInputStream 负责接收信息,如果发送方的信息没有发送来的话,接收方就会处于阻塞状态,一直等待。
Demo:
PipedInputStream
/** *Apr 5, 2013 *Copyright(c)JackWang *All rights reserve *@Author <a href="mailto:[email protected]">JackWang</a> */ package com.myjava.function; import java.io.IOException; import java.io.PipedInputStream; public class PipedIn implements Runnable{ PipedInputStream pipIn = new PipedInputStream(); /** * @param pipIn */ public PipedIn(PipedInputStream pipIn) { this.pipIn = pipIn; } @Override public void run() { byte[] buf = new byte[1024]; try { int len = pipIn.read(buf); System.out.println(new String(buf,0,len)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { pipIn.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
/** *Apr 5, 2013 *Copyright(c)JackWang *All rights reserve *@Author <a href="mailto:[email protected]">JackWang</a> */ package com.myjava.function; import java.io.IOException; import java.io.PipedOutputStream; public class PipedOut implements Runnable { PipedOutputStream pipOut = new PipedOutputStream(); /** * @param pipOut */ public PipedOut(PipedOutputStream pipOut) { this.pipOut = pipOut; } @Override public void run() { String str = "嘿嘿,我来啦!!!"; try { Thread.sleep(5000); //模拟线程阻塞 pipOut.write(str.getBytes()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { pipOut.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
/** *Apr 5, 2013 *Copyright(c)JackWang *All rights reserve *@Author <a href="mailto:[email protected]">JackWang</a> */ package com.myjava.function; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; public class PipedIOTest { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { PipedInputStream in = new PipedInputStream(); //管道输入流 PipedOutputStream out = new PipedOutputStream(); //管道输出流 in.connect(out); //连接管道 PipedIn pIn = new PipedIn(in); PipedOut pOut = new PipedOut(out); new Thread(pIn).start(); new Thread(pOut).start(); } }
------------------------------------------------------------------------------