所有类的根接口:InputStream/OutputStream
一、底层的还是装饰的
1、底层的直接与文件系统或者硬件打交道的类(充当数据源的类):
包括InputStream和OutPutStream两大类,分别用于输入和输出,数据源可以是bytes array,String对象,file文件,stream序列等:
- FileInputStream/FileOutputStream
- ByteArrayInputStream/ByteArrayOutputStream
- StringBufferInputStream/StringBufferOutputStream
等,具体参看下面的java io类图
2、充当装饰功能的io类,通过装饰底层的类来实现更高级的功能,继承自FilterOutputStream/FilterOutputStream,包括:
- BufferedOutputStream/BufferedInputStream
- Datainputstream/Dataoutputstream
等,具体参看下面的java io类图
使用FilterOutputStream/FilterOutputStream时,首先创建一个数据源IO,然后根据需要的功能创建装饰类io,其构造函数的参数为已创建的数据源io。
二、面向字符还是面向字节
同时,java的IO体系又可以分成:inputStream/outputStream和reader/writer两类:
(1) Reader/Writer是面向Unicode字符的(Characters)
(2) InputStream/OutputStream是直接面向字节的(bytes)。
Reader/Writer继承体系之所以存在,最重要的原因是为了国际化,旧式I/O stream 的继承体系仅仅支持8-bit byte stream,而且无法处理16-bit unicode 字符。由于unicode被用于字符国际化,所以加入Reader/Writer以便在所有的io动作上提供对unicode的支持。
几乎所有的java io stream classes都有相应的Reader和Writer来提供对unicode的支持,但是在某些场合,使用byte-oriented InputStream和OutPutStream才是正取的方法,最合理的方式是尽可能先尝试使用Read和Writer,其次才使用byte-oriented库。
三、从InputStream/OutPutStream到Reader/Writer的转换
InputStreamReader和OutputStreamWriter,可以把一个以字节为导向的stream转换成一个以字符为导向的stream。
Java 1.0 class(byte oriented) Java 1.1 class(unicode character oriented)
装饰前的行为
InputStream Reader 转换器:InputStreamReader
OutputStreamReader Writer 转换器:OutputStreamWriter
FileInputSream FileOutputStream
FileReader FileWriter
StringBufferInputStream StringReader/StringWriter
ByteArrayInputStream ByteArrayOutputStream
CharArrayReader CharArrayWriter
装饰后的行为
BufferedInputStream BufferedOutputStream
BufferedReader BufferedWriter
PrintStream PrintWriter
四、示例
DataInputStream和DataOutputStream
Java中除了二进制文件和使用文本文件外还有基于Data的数据操作,这里的Data指的是Java的基本数据类型和String。基本数据类型包括byte、int、char、long、float、double、boolean和short。
例子:
protected void connect (Socket socket)
throws IOException, SocketException
{
this.socket = socket;
applyTimeout();
serverIn = new DataInputStream (
new BufferedInputStream (socket.getInputStream ())
);
serverOut = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream(), 2048)
);
usable = true;
cnt[CONNECT]++;
setChanged();
notifyObservers();
}
在DataInputStream和DataOutputStream两个类中的方法都很简单,基本结构为readXXXX()和writeXXXX()其中XXXX代表基本数据类型或者String。