IO
Java的I/O是实现输入和输出的基础。Java中把不同的输入/输出源(键盘,文件,网络连接等)抽象表述为“流”(stream)。这样就可以做到设备、平台无关的。
分类
Java中I/O类分两两类:字节流和字符流。每种又分输入流和输出流。
字节流
字节流:字节流处理单元为1个字节,操作字节和字节数组。即byte类型数据。
注意:上图中有两个类对其父类有单项关联关系。记住这点,待会儿会讲。
FilterInputStream继承并依赖父类
public class FilterInputStream extends InputStream {
/**
* The input stream to be filtered.
*/
protected volatile InputStream in;
// ...
}
FilterOutStream继承并依赖父类
public class FilterOutputStream extends OutputStream {
/**
* The underlying output stream to be filtered.
*/
protected OutputStream out;
// ...
}
字符流
字符流:字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串。
类图
注意:Flushable:表示刷新,清空内存中的数据
装饰者模式
装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
1.将被装饰者(Concrete Component)当做类中一个成员变量。
2.利用构造将被装饰者注入
该模式类图如下:
解释:
角色 | 模式中的作用 | IO中对应类 |
抽象构件角色 (Component) |
给出一个抽象接口,以规范准备接收附加责任的对象。 | InputStream |
具体构件角色 (Concrete Component) |
将要动态附加责任的类 | ByteArrayInputStream StringBufferInputStream FileInputStream |
装饰角色 (Decorator) |
持有一个构件(Component)对象的引用, 并定义一个与抽象构件接口一致的接口 |
FilterInputStream |
具体装饰角色 (Concrete Decorator) |
给构件对象“贴上”附加的责任 | PushbackInputStream BufferedInputStream DataInputStream LineNumberInputStream |
即如下图:
举个例子,字节流都是每次读取一个字节,BufferedInputStream使用缓冲读取(一次一个数组长度),显然速度会快些。我们利用它读取一个文件流。
public void testDecorator() {
try (FileInputStream fis = new FileInputStream("d:\\hustzw-soapui-project.xml")) {
// 使用装饰模式,把fis装饰进去bis中。使用缓冲读取速度变快
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] res = new byte[1025];
int b;
while ((b = bis.read(res)) != -1) {
System.out.println(new String(res));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
对应的字节输出流也是如此:
public void testDecoratorOutput() {
String s = "使用装饰模式,把fileStream装饰进去buffer中。使用缓冲一次写入多个字节";
try (FileOutputStream fileStream = new FileOutputStream("d:\\zw.txt")) {
BufferedOutputStream buffer = new BufferedOutputStream(fileStream);
buffer.write(s.getBytes());
buffer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
另外,对于字符流,同样如此。
public void testReader() {
try (FileReader fr = new FileReader("d:\\hustzw-soapui-project.xml")) {
BufferedReader br = new BufferedReader(fr);
int b;
char[] res = new char[1024*1024];
while ((b = br.read(res)) != -1) {
System.out.println(new String(res));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
当然也可以使用,BufferedReader实例的readLine() 方法。