2019.07.19(day16)
●字节流(低级流)
可以从或向一个特定的方向读写数据,数据是字节
InputStream:
是所有字节流的父类,其定义了基础的读取方法
-int read()
读取一个字节,以int形式返回,该int的低8位有效
返回-1,表示文件末尾EOF end of file
-int read(byte[] b)
将输入流中的最多len个数据字节写入byte数组
返回值为实际读取字节量的长度
返回-1,表示文件末尾EOF end of file
-int read(byte[] b,int offset,int len)
将输入流中的最多len个数据字节写入byte数组
从offset的位置开始写入数组,不能超过数组的实际长度
如果超过数组的实际长度会报数组越界异常
-void close()
关闭此输入流并释放与该流有关的系统资源
OutputStream:
是所有字节流的父类,其定义了基础的写出方法
-void write(int d)
写出整型数据的低8位
-void write(byte[] b)
给指定的字节数组数据全部输出
-void write(byte[] b,int offset,int len)
给指定的字节数组从偏移量offset开始的len个字节写入输出流
-void flush()
刷新此输出流并强制写出所有缓冲的输出字节
-void close()
关闭此输出流并释放与此有关的所有的系统资源
FileInputStream:文件输入流
-可以操作文件的内容
-操作的是字节流
-继承自InputStream抽象类
-低级流
-操作的是文件
FileOutputStream:文件输出流
-可以操作文件的内容
-操作的是字节流
-继承自OutputStream抽象列
-低级流
-操作的是文件
●封装流/处理流:(高级流/过滤流)
针对字节流进行封装,即对一个已经存在的流进行封装
通过所有的封装类能够对数据更有效的读写
封装类的底层还是字节流
缓冲流(Buffer):
缓冲流原理:
向硬件和存储设备操作数据时会加大与硬件的交互次数,从而降低读写的速度
做缓冲流的目的就是减少与硬件的交次数
缓冲输出流的原理:
BufferedOutputStream缓冲输出流内部会维护一个缓冲区
每当向该流写出数据时,都会先将数据存入缓冲区
当缓冲区满后,缓冲流会将数据一次性写出
缓冲输入流的原理:
BufferedInputStream缓冲输入流内部会维护一个缓冲区
每当向该流读入数据时,都会将数据存入缓冲区,read方法会从缓冲区读取数据
当数据全部读取完毕后,再次read,又会把缓冲区填满
read逐一在缓冲区读取数据,以此往复
注意:
缓冲是靠牺牲内存来提升io的读写效率
void flush(),清除缓冲区,将缓冲区的数据强制写出,保证数据的完整性
对象流:
把内存的对象数据,序列化到硬盘上,也可以把硬盘上的文件反序列化回内存的对象
序列化:
把内存的对象序列化到硬盘上,以字节的方式体现
反序列化:
把硬盘上的字节序列,反序列化回内存中的对象
如:
Student stu=new Student("张三",20,"s001");
stu-->硬盘上(序列化)-->内存堆中出现stu对象(反序列化)
注意:
如果要实现对象的序列化和反序列化,就必须对序列化的对象所对应的类实现java.io. Serializable接口,且类中最好提供一个long类型的序列化版本号
如:
public class Student implements Serializable{
private static final long serialVersionUID=长整型的数据;
field 属性
method 方法
}
Serializable接口:
此接口仅表示可序列化语义
某个类实现这个接口就表示这个类可以序列化这个语义
这个类的子类也具备序列化语句,需要提供一个常量serializableUID来表示本类的序列化版本号
如果想跨平台,就需要声明一个版本号,且两个平台两端的版本必须相同
序列化类中可以有很多的属性,但部分属性不想被序列化和反序列化
可以用transient修饰不想被序列化和反序列化的属性
transient:瞬间的,短暂,临时的 如:
public class Student implement Serializable{
private static final long serialVersionUID = 1L;
private transient String name;//不可序列化
private int age;//可以序列化
field 属性
method 方法
}