java IO类库总结

最近在看设计模式,上面介绍到装饰模式时引用到了IO类库作为例子,想写一个简略的总结
在java中,io基本上分为字节流和字符流两大类,字节流以InputStream和OutputStream为顶层类

结构

InputStream (abstract)
      FileInputStream
      FileterInoutStream
            BufferedInputStream (支持mark/reset)
            DataInputStream (有自动读入基本类型数据的方法)
            PushbackInputStream(不支持mark/reset)  
     ObjectInputStream
     ByteArrayInputStream 复制代码

inputStream

该类是一个抽象类,是字节输入流的超类,此类中包括了文件操作的一些基本方法

available()
    返回可读取的字节数,此方法在改类中总是返回0复制代码
mark/reset()
    标记与返回 另外有mark方法设置最大读取字节,超过字节数就回来了。本类中依旧不能使用复制代码
read
    该类中共有三各read方法,无参,一个字节数组,以及字节数组加上规定的读入地址和读入长度。读取出的字节会覆盖原来有的数据(如果该位有的话)复制代码

FileInputStream

在java api中 对该类定义为:从文件系统中读取字节流。如音频,图像之类的字节流数据用该类读取。

FileterInoutStream

此类作为装饰类的父类,包含一个基本输入流,为数据的读取提供一些额外的功能,这些功能应该在其子类实现

DataInputStream

该类扩展了父类的方法,主要用于读取java基本类型数据

ObjectInputStream

该类主要实现类读取java对象的功能,最主要的用途在于对象的序列化与放序列化。
注意,实现序列化需要实现serializable 接口,该接口可以继承,

当子类与父类都实现serializable接口

public class User implements Serializable{
    public  int i=10;
    public String name="zhaosi";
    public User() {
        System.out.println("user constructor");
    }
    public User(String name){
     this.name=name;
    }
}复制代码
public class Person extends User{
    static int sb=10;
    int b=11;
    public Monkey m =new Monkey();
    public Person() {
    }
     public void say(){
         System.out.println(b);
     }
}复制代码
public class ObjectStream {
    public static void main(String[] args) {
        ObjectOutputStream oo = null;
        ObjectInputStream oi = null;
        try {
            oo = new ObjectOutputStream(new FileOutputStream(new File("./object.txt")));
            oi = new ObjectInputStream(new FileInputStream(new File("./object.txt")));
            Person p = new Person();
            p.name="wangwu";
            oo.writeObject(p);
            Person pp = (Person) oi.readObject();
            System.out.println(pp.name);
        }catch(Exception e){
        }
        finally {
            try {
                oo.close();
                oi.close();
            } catch (Exception e2) {}}}}复制代码

···
public class Monkey implements Serializable {
public Monkey() {
System.out.println("monley constructor");
}
public int i=20;
public void sys(){
System.out.println("monley");
}
public String toString(){
return "Monkey";
}
}
···

结果
user constructor
monley constructor
wangwu
即如果与要持久化关联的对象都实现serilized接口的话,存入该对象时一同存入与其关联的对象

当父类未持久化时

修改上述文件 将user类 serializable 接口去除,person 实现serializable接口

运行结果
    user constructor
    monley constructor
    user constructor
    zhaosi复制代码

java api 中有此解释:

对于没有实现 java.io.Serializable 接口的任何对象,序列化不会对其字段进行读取或赋值。非 serializable 的 Object 的子类可以为 serializable。在此情况下,非 serializable 类必须具有无参数的构造方法以允许其字段能被初始化。在此情况下,子类负责保存和恢复非 serializable 类的状态。经常出现的情况是,该类的字段是可访问的(public、package 或 protected),或者存在可用于恢复状态的 get 和 set 方法

我理解的大致意思为,当父类未实现Serializable接口,该对象不会序列化,当子类反序列化取出来时候,子类重新创建一个父类对象,原来对与父类相关的改变丢失。

当内部成员Mokey未实现Serializable
去除Mokey类Serializable 接口
结果
user constructor
monley constructor
person constructor
java.io.NotSerializableException: TestIO.Monkey
进程终止

PushbackInputStream

此类可支持回退操作,其构造参数传入一个缓冲区,当缓冲区为空时,读操作调用底层的read方法,如果缓冲区不为空,则先读取缓冲区

 public class PushbackInputStreamTest {
    public static void main(String[] args) {
        PushbackInputStream ps =null;
        ByteArrayInputStream bs=null;
        String str ="haha,nihao";
        try {
            bs= new ByteArrayInputStream(str.getBytes());
            ps = new PushbackInputStream(bs);
            int temp =0;
            while((temp=ps.read())!=-1){
                if(temp == ','){
                    ps.unread(temp);
                    temp=ps.read();
                    System.out.println("(回退"+(char)temp+")");
                }else{
                    System.out.println((char)temp);
                }
            }
        }catch(Exception e){
            e.getMessage();
        }
    }
}复制代码

PushbackInputStream ,ByteArrayInputStream 不用关闭

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值