I/O类库经常使用流这个抽象概念,它表示任何有能力产出数据的数据源对象或有能力接收数据的接收端对象。
正如我们所知,I/O类的设计思想是装饰器设计模式。即在基础类对象上叠加其他类对象。即:创建单一的结果流,却需要创建多个对象。
I/O类的结构图:
现以InputStream为例进行讲解。
InputStream类可以用来表示从不同数据源产生输入的类,这些数据源可以包括:
- 字节数组 ByteArrayInputStream
- String对象 StringBufferInputStream
- 文件 FileInputStream
- 管道 PipedInputStream
- 其他流组成的序列,可以用以收集合并到一个流内
其他数据源(如Internet连接)
每一种数据源都有相应的类。另外FilterInputStream也属于一种InputStream,为装饰器(decorator)类提供基类。
- DataInputStream 包含用于读取基础类型数据的全部接口
- BufferedInputStream 使用它主要是为了防止每次读取仅进行实际的“写”操作,加快读取速度。
- LineNumberInputStream 跟踪输入流中行号
- PushbackInputStream 具有能“弹出一个字节的缓冲区”。可以将读到的最后一个字节回退。
Java I/O操作尽量使用针对字符(Reader, Writer)的而非针对字节的*(InputStream,* OutputStream)。**
BufferedOutputStream(Input也一样)对数据流进行了缓冲,后再读写。因此是非常常用的。
常见的几种I/O流的示例:
(1)
package test;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferedInputFile {
public static String read(String name) throws IOException{
BufferedReader in = new BufferedReader(new FileReader(name));//增加读取速度
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine()) != null){
sb.append(s + "\n");
}
in.close();
return sb.toString();
}
public static void main(String args[]) throws IOException{
System.out.println(read(".\\src\\test\\BufferedInputFile.java"));
}
}
运行结果为:
成功实现使用FileReader读取File的目的(这里的实现是将File使用BufferedReader读入并输出到console里面)。
(2) 以字节流形式读取内存中的缓存数据
package test;
import java.io.*;
public class FormattedMemoryInput {
public static void main(String args[]) throws IOException{
try{
DataInputStream in = new DataInputStream(new ByteArrayInputStream(BufferedInputFile.read(".\\src\\test\\FormattedMemoryInput.java").getBytes()));
while(true){
System.out.print((char)in.readByte());
}
}catch(EOFException ex){
System.err.println("End of Stream");
}
}
}
输出结果为:
package test;
import java.io.*;
public class FormattedMemoryInput {
public static void main(String args[]) throws IOException{
try{
DataInputStream in = new DataInputStream(new ByteArrayInputStream(BufferedInputFile.read(".\\src\\test\\FormattedMemoryInput.java").getBytes()));
while(true){
System.out.print((char)in.readByte());
}
}catch(EOFException ex){
System.err.println("End of Stream");
}
}
}
End of Stream
上例中:
BufferedInputFile.read(“.\src\test\FormattedMemoryInput.java”)将File文件读取为String对象,并存放在内存中。ByteArrayInputStream是指以字符串的形式读取,而DataInputStream为一个FilterInputStream(修饰器类),其中包含了readByte()方法(以字节形式读取)。
这个示例比较好的演示了装饰器的使用。
I/O操作太多了,nio包也很复杂。等到什么时候具体需要用到,再另开博客专门讲解吧。