首页 > 代码库 > java里IO流的逻辑关系

java里IO流的逻辑关系

      在InputStream里和OutputStream里,提供了以下的针对不同信息来源的IO处理对象:

1)以字节形式,读写内存缓冲区中内容得到的ByteArrayInputStream和ByteArrayOutputStream对象

2)以字符串为对象,读写String累心数据的StringBufferInputStream和StringBufferOutputStream对象。

3)针对文件读写操作的FileInputStream和FileOutputStream对象。

4)针对管道数据读写操作的PipedInputStream和PipedOutputStream对象。


上述IO类,从字面含以上来看,可以容纳从不同设备读写的数据,但是它们的功能不限于此。它们更像是连接到各设备的管道,我们可以通过new语句,来创建与内存缓冲区等链接通道,并通过Input类型的read方法和Output类型的write方法,来执行读写操作。


与之相对应的,为了可以容纳16位Unicode编码,JDK1.1以上提供了如下的Reader和Writer的IO对象:

1)用来读写内存缓冲数据区的CharArrayReader和CharArrayWrite对象,它们同ByteArrayInputStream和ByteOutputStream对应。

2)用来读写String类型数据的StringReader和StringWrite对象,它们同StringBufferInputStream和StringBufferOutputStream对应。

3)用来读写文件数据的FileReader和FileWrite对象,它们同FileInputStream和FileOutputStream对应。

4)用来管道操作的PipedReader和PipedWrite对象,它们同PipedInputStream和PipedOutputStream对应。


值得注意的是,管道的IO操作方法,主要用于Linux里的线程通讯里,在Windows下使用的机会较少。


我们使用上述Input和Output(或Reader和Writer对象),确实可以完成IO操作,但是会发现没中不足。比如,我们从缓冲区里得到的是数据流,而无法更精确地读取int、char等基本类型的数据。又如,我们从文件里读取数据的时候,无法立即精确地读到某一位置的数据。

我们不应该把上述的辅助“功能”封装在IO流对象中,因为这样做会让IO流在读写数据的职责外,再负责其他类型逻辑的操作。所以,在java的IO类中,还专门有一种负责“优化IO流功能”的“装饰器”的类。这些装饰器类从输入和输出的角度,可以分为Input和Output两类,从所处理的字符集角度,可以分为Stream和Reader两类。


不同装饰器可以完成不同的工作:

1)DataInputStream和DataOutputStream可以从Stream里读取到基本类型(如Int等)的数据,通过他们提供的readByte和readDouble方法,可以直接从缓冲区里读取到特定类型的数据。同样地,BufferedReader和BufferedWriter用来从Reader和Writer里读取基本类型的数据。

2)BufferedInputStreamI和BufferedOutStream里面封装了各种类型缓存区里读写指定数量数据的方法,同样地,BufferedReader和BufferedWriter是它们对应的类。

3)PrintStream可以产生指定格式的输出,PrintWriter是它的对应类。用它可以直接把int等类型的数据写道缓冲区里。

4)LineNumberInputStream对象可以用来统计input stream对象里的行数,而LineNumberReader是它对应的类。

5)RandomAccessFile类可以用来读取指定文件里具体位置的数据。

6)StreamTokenizer类用来根据InputStream里面的分割为记号(Token),把输入流分割成若干文本块。


装饰类不可以独立的工作,它们只是为特定的IO操作提供锦上添花的功能,通过使用这些装饰类,我们可以大大简化用java读写特定设备的工作。


现在归纳一下,上面谈到了三种IO类型的对象,它们分别是InputStream和OutputStream类型的只可以容纳8为字节编码的对象,Reader和Writer可以容纳16为字节编码的对象和用来完善输入输出操作功能的“装饰”类。


下面附上一段读写内存数据的代码

import java.io.IOException;
//import java.io.StringBufferInputStream;
import java.io.StringReader;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.StringReader;

public class IOExample1 {
	public static void main(String[] args){
		try{
			String memInput="Input into Memory!";
			StringReader sin=new StringReader(memInput);
			int singleWord;
			PrintStream outToFile=
				new PrintStream(new BufferedOutputStream(new FileOutputStream("D:\\1.out")));
			//通过循环,写文件
			while((singleWord=sin.read())!=-1){
				outToFile.print((char)singleWord);
				System.out.print((char)singleWord);
			}
			sin.close();
			//强制输出到缓冲区
			outToFile.flush();
			outToFile.close();
		}catch(FileNotFoundException e){
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}	
	}
}



java里IO流的逻辑关系