IO流(二)

IO(二)

要点
1)掌握字节流和字符流的各种类
2)熟练应用序列化与反序列化

字节流

 

InputStream : 
	 FileInputStream  从文件读取字节
	 BufferedInputStream 加入缓冲功能,提高文件的读取效率
	 ByteArrayInputStream 从字节数组变成输入流

OutputStream :
FileOutputStream 向文件写入字节
BufferedOutputStream 加入缓冲功能, 提高文件的写入效率
ByteArrayOutputStream 把流的内容写入字节数组
PrintStream 实际上就是 System.out

字符流

 

Reader :
	 InputStreamReader 转换字节流为字符流
	 BufferedReader 功能增强,以行为单位读取数据 (装饰器模式)
	 FileReader  是InputStreamReader子类,将字符编码固定为操作系统的默认编码,不能手工改动
Writer :
	  OutputStreamWriter 转换字节流为字符流
	  PrintWriter 以行为单位写入数据
	  write 当成字符写入
	  print  print就是将参数转为字符串后写入
	  FileWriter 是OutputStreamWriter的子类,也是固定了字符编码

序列化

1.让类实现Serializable序列化接口
2.使用ObjectOutputStream 写入要序列化的对象

例 :

public class Student implements Serializable{

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
Student student = new Student();
student.setId(1);
student.setName("张三");
// 序列化就是将对象变为输出字节流
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("d:\\student.obj"));
os.writeObject(student);
os.close();

注意
要求对象中所有属性均为可序列化,不想序列化的属性加transient关键字

反序列化

用ObjectInputStream读取字节内容,还原为java对象

例 :

ObjectInputStream is = new ObjectInputStream(new FileInputStream("d:\\student.obj"));
        Student s = (Student)is.readObject();
        System.out.println(s.getId());
        System.out.println(s.getName());

注意
1)可以写入和读写基本数据类型,但是读取与写入顺序必须一致
2)读取与写入顺序不一致,或者读取多于写入,会出现EOFException
3)建议在写入最后一个对象时使用null用于判断是否读取完毕

创建对象的方法:

方法一 : new出来一个对象
方法二 clone
特点 :
1)属于浅拷贝,如果属性为引用类型,复制的仅是地址。没有为这个属性创建新的对象
2)对应的设计模式为原型(prototype)模式 ,不走构造方法
3)需要实现Cloneable接口,重写clone方法

例 :

public class Teacher implements Cloneable{ // 可克隆的

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // 必须调用Object父类的克隆方法
        return super.clone();
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher t = new Teacher();
        t.setId(1);
        t.setName("李四");
        Teacher t2 = (Teacher)t.clone();
        System.out.println(t2.getId());
        System.out.println(t2.getName());
        System.out.println(t2 == t);//不等,证明是新的对象
    }
}

方法三: 序列化与反序列化
属于深拷贝,用序列化和反序列化生成新的对象,也会为属性创建新的对象

例 :

public class Teacher2 implements Serializable{

    private int id;
    private String name;
    private Date birthday;

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Teacher2 clone() {
        try {
            // 序列化
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream os = new ObjectOutputStream(bos);
            os.writeObject(this); // 写入当前对象
            byte[] bytes = bos.toByteArray(); // 字节结果

            // 反序列化
            ObjectInputStream is = new ObjectInputStream(new ByteArrayInputStream(bytes));
            Teacher2 t = (Teacher2)is.readObject();
            return t;
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        Teacher2 t = new Teacher2();
        t.setId(1);
        t.setName("王五");
        t.setBirthday(new Date());
        Teacher2 t2 = t.clone();
        System.out.println(t == t2);
        System.out.println(t.getBirthday() == t2.getBirthday());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值