IO2——字节流
字节流抽象类
-
字节流的父类(抽象类) :
- InputStream:字节输入流
- OutputStream:字节输出流
文件字节流
FileInputStream
- public int read(byte[] b) //从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。read()一个字节一个字节读取
- 构造方法:FileInputStream(String name)、FileInputStream(file)
单字节读取
结果:读出来是abcdefg的ascii码
可以加char并且使用print不换行
结果:
一次读取多个字节
结果:
用循环做优化:
结果:
可以利用byte[] buf=new byte[1024]
再次进行改进,从而使数据一次性读完
FileOutputStream
- public void write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流。
注意:97是a的ASCII码
- 也可以将字符串写入
调用getBytes方法,会覆盖之前的,重新写入
如果不想覆盖可以:helloworldhelloworld
字节流复制文件
fos.write(buf,0,count),这样写是为了防止最后的读入时不够1024个
字节缓冲流
BufferedInputStream
单字节读取
需要一个字节输入流
结果:
也可自己创建一个缓冲区
BufferedOutputputStream
使用字节缓冲流来写入文件
需要一个字节输出流
结果:
注意:一定要用flush刷新到硬盘,否则如果不超过8k的话,他就直接写在了缓冲区中
对象流
-
对象流: ObjectOutputStream/ObjectInputStream
使用流传输对象的过程称为序列化(写)、反序列化(读)。
序列化
使用ObjectOutputStream
- 创建一个学生类
- 使用 ObjectOutputStream实现对总的序列化
使用ObjectOutputStream必须要有节点流
ObjectOutputStream.close中本身有flush,所以可不用再次调用flush进行刷新
结果:
有异常,说我们这个类不能序列化!我们这个类要想序列化,这个类必须实现Serializable接口,这个接口仅仅是标记一下这个类可以序列化,这个接口里面没有任何的常量和方法!
反序列化
使用ObjectInputStream(读取重构对象)
如果再次读第二次的时候,会抛出异常!
序列化和反序列化注意事项
(1)序列化类必须要实现Serializable接口
(2)序列化类中对象属性要实现Serializable接口
(3)序列化版本号ID,保证序列化的类和反序列化的类是同一个类
在我们实现Serializable接口之后,会有一个提示
serialVersionUID:序列化版本号ID
(4)使用transient (瞬间的)修饰属性,这个属性不能序列化
(6)静态属性不能序列化
(7)序列化多个对象,可以借助集合来实现
序列化
反序列化
这样多两次比较麻烦,我们可以利用之前学过的集合
序列化
反序列化