前言
本次学习将获取以下知识
- 理解Java l/O系统。
- 熟练使用java.io包中的相关类与接口进行I/O编程。
- 掌握Java l/O的设计原则与使用的设计模式。
相关概念
流的概念
- Java程序通过流来完成输入/输出。流是生产或消费信息的抽象。流通过Java的输入/输出系统与物理设备链接。尽管与它们链接的物理设备不尽相同,所有流的行为具有同样的方式。这样,相同的输入/输出类和方法适用于所有类型的外部设备。这意味着一个输入流能够抽象多种不同类型的输入:从磁盘文件,从键盘或从网络套接字。同样,一个输出流可以输出到挫制台、磁盘文件或相连的网络。流是处理输入/输出的一个洁净的方法,例如它不需要代码理解键盘和网络的不同。Java中流的实现是在java.io包定义的类层次结构内部的。
输入/输出流
- 输入/输出时,数据在通信通道中流动。所谓“数据流(stream)"指的是所有数据通信通道之中,数据的起点和终点。信息的通道就是一个数据流。只要是数据从一个地方“流"到另外一个地方,这种数据流动的通道都可以称为数据流。
- 输入/输出是相对于程序来说的。程序在使用数据时所扮演的角色有两个:一个是源,一个是目的。若程序是数据流的源,即数据的提供者,这个数据流对程序来说就是一个“输出数据流"(数据从程序流出)。若程序是数据流的终点,这个数据流对程序而言就是一个“输入数据流”(数据从程序外流向程序)。
- 两种基本的流是:输入流(Input Stream)和输出流(Output Stream)。可从中读出一系列字节的对象称为输入流。而能向其中写入一系列字节的对象称为输出流。
输入/输出的类
- 在java.io包中提供了60多个类(流)。
- 从功能上分为两大类:输入流和输出流。
- 从流结构上可分为字节流(以字节为处理单位或称面向字节)和字符流(以字符为处理单位或称面向字符)。
- 字节流的输入流和输出流基础是InputStream和OutputStream这两个抽象类,字节流的输入输出操作由这两个类的子类实现。字符流是以字符为单位进行输入输出处理的流。
- 字符流输入输出的基础是抽象类Reader和Writer。
字节流和字符流
- 两种类型的流:字节流和字符流。
- 字节流(byte stream)为处理字节的输入和输出提供了方便的方法。例如使用字节流读取或写入二进制数据。
- 字符流(character stream)为字符的输人和输出处理提供了方便。它们采用了统一的编码标准,因而可以国际化。当然,在某些场合,字符流比字节流更有效。
需要声明:在最底层,所有的输入/输出都是字节形式的。基于字符的流只为处理字符提供方便有效的方法
读写数据的逻辑
- 输入流,读数据的逻辑
- open a stream
- while more information
- read information
- close the stream
- 输出流,写数据的逻辑
- open a stream
- while more information
- write information
- close the stream
流只能是一种,要么只输出要么只输入,流都要open,read/write,close。
流的分类
- 节点流︰从特定的地方读写的流类,例如:磁盘或一块内存区域。直接和数据的源头连接。
- 过滤流∶使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或输出流连接创建的。操作节点流,比如将其进行包装。变成Buffer等。
InputStream
- InputStream中包含一套字节输入流需要的方法,可以完成最基本的从输入流读人数据的功能。当Java程序需要外设的数据时,可根据数据的不同形式,创建一个适当的InputStream子类类型的对象来完成与该外设的连接,(节点流) 然后再调用执行这个流类对象的特定输入方法来实现对相应外设的输入操作。
- InputStream类子类对象自然也继承了InputStream类的方法。常用的方法有:读数据的方法read(),获取输入流字节数的方法available(),定位输入位置指针的方法skip()、reset()、mark()等。
OutputStream
- 三个基本的写方法
- abstract void write(int b):往输出流中写人一个字节。
- void write(byte[] b):往输出流中写人数组b中的所有字节。
- void write(byte[] b, int off, int len) :往输出流中写人数组b中从偏移量off开始的len个字节的数据
- 其它方法void flush():刷新输出流,强制缓冲区中的输出字节被写出。
- OutputStream是定义了流式字节输出模式的抽象类。该类的所有方法返回一个void值并且在出错情况下引发一个IOException异常。
I/O流的链接
- 过滤流差不多就是给节点流进行功能增强。将其变成buffer,再将其变成特定的数据类型。
Java I/O库的设计原则
- Java的I/O库提供了一个称做链接的机制,可以将一个流与另一个流首尾相接,形成一个流管道的链接。这种机制实际上是一种被称为Decorator(装饰)设计模式的应用。
- 通过流的链接,可以动态的增加流的功能,而这种功能的增加是通过组合一些流的基本功能而动态获取的。
- 我们要获取一个I/O对象,往往需要产生多个I/O对象,这也是JavaI/O库不太容易掌握的原因,但在I/O库中Decorator模式的运用,给我们提供了实现上的灵活性。
装饰者模式
- 不通过继承来增强对象的功能。
- 装饰者继承自被装饰(增强)的对象,且也是抽象的。
- 装饰者中有被装饰的对象
- 装饰者重写(增强)了被装饰者的方法,一般在重写的方法中,会调用一下被装饰者的方法。
- 注意点
- 装饰者模式通常采用抽象类
- 装饰者其实就是将被装饰者再次封装
new BufferedInputStream(new ByteInputStream());//Buffered就是装饰者,ByteInput就是被装饰者
复制代码