复习day7
一. 字节流和字符流
区别
字符流是字节流的包装,字符流则是直接接受字符串,它内部将串转成字节,再写入底层设备.
读写的时候字节流是按字节读写,字符流按字符读写。
字节流适合所有类型文件的数据传输,因为计算机字节(Byte)是电脑中表示信息含义的最小单位。字符流只能够处理纯文本数据,其他类型数据不行,但是字符流处理文本要比字节流处理文本要方便。
字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件
在硬盘上的所有文件都是以字节形式存在的(图片,声音,视频),而字符值在内存中才会形成。
二. 字节流和字符流API
字节流
字节输入流
常用方法:
int read()// 读取并返回1字节数据,若返回-1,表示读到了输入流的末尾。
int read(byte[] b)// 将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾。
int read(byte[] b, int off, int len)//将数据读入一个字节数组,同时返回实际读取的字节数。如果返回-1,表示读到了输入流的末尾,off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字节数。
long skip(long n)// 跳过和丢弃此输入流中数据的n个字节
void close()// 关闭此输入流并释放与该流关联的所有系统资源。
字节输出流
常用方法:
void write(byte[] b)// 将b.length个字节从指定的byte数组写入此输出流
void write(byte[] b, int off, int len)// 将指定byte数组中从偏移量off开始的len个字节写入此输出流
void write(int b)// 将1字节写入此输出流
void close() // 关闭此输出流并释放与此流有关的所有系统资源
void flush() // 刷新此输出流并强制写出所有缓冲的输出字节
字符流
字符输入流
常用方法:
int read()// 读取并返回1字符数据,若返回-1,表示读到了输入流的末尾。
int read(char[] b)// 将数据读入一个字符数组,同时返回实际读取的字符数。如果返回-1,表示读到了输入流的末尾。
int read(char[] b, int off, int len)//将数据读入一个字符数组,同时返回实际读取的字符数。如果返回-1,表示读到了输入流的末尾,off指定在数组b中存放数据的起始偏移位置;len指定读取的最大字符数。
long skip(long n)// 跳过和丢弃此输入流中数据的n个字符
void close()// 关闭此输入流并释放与该流关联的所有系统资源。
字符输出流
常用方法:
void write(char[] b)// 将b.length个字符从指定的byte数组写入此输出流
void write(char[] b, int off, int len)// 将指定byte数组中从偏移量off开始的len个字符写入此输出流
void write(int b)// 将1字符写入此输出流。
void write(String b)// 将字符串写入此输出流
void close() // 关闭此输出流并释放与此流有关的所有系统资源
void flush() // 刷新此输出流并强制写出所有缓冲的输出字符
三. 分类
按照流的方向:输入流(inputStream)和输出流(outputStream);
按照实现功能分:节点流(可以从或向一个特定的地方读写数据,如 FileReader)和拓展流(是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写, BufferedReader)
采用了”装饰器设计模式思想”
**节点流才具备真正操作文件的能力.**拓展流只是让流的功能更加强大而已,拓展流脱离了节点流的话,那么是不允许的.
拓展流的使用必须要建立在节点流的基础之上.;
- 按照处理数据的单位: 字节流和字符流。分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。Java中其他多种多样变化的流均是由它们派生出来的。
四. 装饰器模式
装饰器模式又名包装(Wrapper)模式
- 在不改变对象现有结构的情况下,动态的给对象添加额外的功能
- 相比于继承,装饰器模式能对不支持继承的类进行增强;并且比继承更灵活,不需要生成大量的子类
在装饰器模式中的角色有:
- 抽象构件(Component)角色:给出一个抽象接口,已规范准备接收附加责任的对象。
- 具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类
- 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
- 具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。
装饰模式的优点
- 装饰模式与继承关系的目的都是要拓展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者“除掉”一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。
- 通过不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出更多不同行为的组合。
装饰模式的缺点
由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另外一方面,使用装饰模式会产生比使用继承关系所产生的更多的对象。而更多的对象会使得查找错误更为困难,特别是这些对象在看上去极为相似的时候。
五. BIO,NIO,AIO
同步IO:用户进程发出IO调用,去获取IO设备数据,双方的数据要经过内核缓冲区同步,完全准备好后,再复制返回到用户进程。而复制返回到用户进程会导致请求进程阻塞,直到I/O操作完成。
异步IO:用户进程发出IO调用,去获取IO设备数据,并不需要同步,内核直接复制到进程,整个过程不导致请求进程阻塞。
阻塞IO调用 :在用户进程(线程)中调用执行的时候,进程会等待该IO操作,而使得其他操作无法执行。
非阻塞IO调用:在用户进程中调用执行的时候,无论成功与否,该IO操作会立即返回,之后进程可以进行其他操作(当然如果是读取到数据,一般就接着进行数据处理)。
同步阻塞
:你到饭馆点餐,然后在那等着,还要一边喊:好了没啊!同步非阻塞
:在饭馆点完餐,就去遛狗了。不过溜一会儿,就回饭馆喊一声:好了没啊!异步阻塞
:遛狗的时候,接到饭馆电话,说饭做好了,让您亲自去拿。异步非阻塞
:饭馆打电话说,我们知道您的位置,一会给你送过来,安心遛狗就可以了。
- BIO:同步阻塞,在服务器中实现的模式为一个连接一个线程。线程发起IO请求后,一直阻塞IO,直到缓冲区数据就绪后,再进入下一步操作。BIO一般适用于连接数目小且固定的架构,这种方式对于服务器资源要求比较高,而且并发局限于应用中,是JDK1.4之前的唯一选择,但好在程序直观简单,易理解。
- NIO:同步非阻塞,在服务器中实现的模式为一个线程处理多个请求(连接),同步指的是必须等待IO缓冲区内的数据就绪,而非阻塞指的是,用户线程不原地等待IO缓冲区,可以先做一些其他操作,但是要定时轮询检查IO缓冲区数据是否就绪。NIO一般适用于连接数目多且连接比较短(轻操作)的架构,并发局限于应用中,编程比较复杂,从JDK1.4开始支持。(间隔轮询,不断发送请求,会消耗cpu资源)
- AIO:异步非阻塞,在服务器中实现的模式为一个有效请求一个线程,用户线程只需要告诉内核,当缓冲区就绪后,通知用户线程或者执行用户线程交给内核的回调函数。AIO一般适用于连接数目多且连接比较长(重操作)的架构,充分调用操作系统参与并发操作,编程比较复杂,从JDK1.7开始支持。