欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(四)IO流——对象流、打印流

程序员文章站 2022-04-03 16:17:26
...

对象流:

使用对象流之前,很明显需要一个自定义的对象

可是普通的自定义类创建的对象并不能被对象流序列化

我们要让这个自定义类实现一个Serializable接口(Serializable是一个标志性接口,接口中无任何内容)

例:(省略了构造方法、get/set方法、toString方法)

public class Person implements Serializable{
    private String name;
    private int age;
}

 

ObjectOutputStream(对象输出流):

对象序列化,将对象以流的形式保存到文件夹的过程

public ObjectOutputStream(OutputStream out)                             创建指定字节输出流的对象输出流对象

File f = new File("a.txt");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);

void  writeObject(Object  obj)                                                                保存对象到流关联的文件中

File f = new File("b.txt");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
Person p = new Person("jack",22);
oos.writeObject(p);
oos.close();

这样就完成了对象的序列化到b.txt:

(四)IO流——对象流、打印流

ObjectOutputStream对象输出流输出的对象文件就是乱码,只能用对象流查看文件内容

 

 

 

ObjectInputStream(对象输入流):

对象反序列化,将文件中对象以流的形式读取出来的过程

public ObjectInputStream(InputStream in)                                 创建指定字节输入流对象的对象输入流对象

File f = new File("b.txt");
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);

public final Object readObject ()                                                         读取一个对象 

File f = new File("b.txt");
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
Object obj = ois.readObject();
System.out.println(obj);                //输出:Person{name='jack', age=22}
fis.close();

 

 

当保存好对象后,若对类的内容作了修改,且没有重新使用对象输出流输出一次关联文件

则readObject()方法读取到的关联文件时就会出现InvalidClassException异常

因为每次修改类内容(无论是,包括修饰符、成员变量、成员方法)都会改变类中的一个serialVersionUID值

然后再次读取该对象文件时,就会出现序列化不同的异常

 

若不想因为对类内容作了一些微小修改,而导致源文件不能被读取的问题

可以在类中固定好serialVersionUID值,且设置为私有final静态的!

public class Person implements Serializable{
    private String name;
    private int age;
    private static final long serialVersionUID = 12345L;        //固定serialVersionUID为任意一个值
}

 

 

若对象序列化时,部分成员变量中的信息,不想被writeObject写进文件中

1.可以将成员变量设置为static静态成员变量

这样改成员变量就保存在类中,创建对象时不会被对象序列化输出到文件中

public class Person implements Serializable{
    private String name;
    private int age1;
    private static final long serialVersionUID = 12345L;
    private static double high ;
}

弊端:设置为静态后,反序列化该对象文件确实不会显示此成员变量

可是所有Person类对象的high属性都是固定的,这样很不灵活、很不实用

 

 

2.使用transient关键字

使用该关键字修饰的成员变量,能保证成员变量的值不被序列化到文件中,只会短暂保存在内存中

public class Person implements Serializable{
    private String name;
    private int age1;
    private static final long serialVersionUID = 12345L;
    private transient int high ;            //transient修饰了high属性
}

做个测试:使用ObjectOutputStream输出带有transient关键字修饰的成员变量

File f = new File("a.txt");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
Person p = new Person("jack",20,22);        //写入被transient关键字修饰的high属性为22
oos.writeObject(p);
oos.close();

然后再用ObjectInputStream查看该对象是否包含该成员变量的信息

File f = new File("a.txt");
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
Object obj = ois.readObject();
Person p = (Person)obj;                     //将Object对象强转为Person对象
System.out.println(p.getHigh());            //输出:0
fis.close();

 

 

打印流:

PrintStream类:

public PrintStream(File file)                                                          使用指定的File对象创建打印流对象

File f = new File("b.txt");
PrintStream ps = new PrintStream(f);

public PrintStream(String fileName)                                           使用指定的文件名字符串创建打印流对象

PrintStream ps = new PrintStream("b.txt");

 

PrintStream类的print()和println()方法中可以输出基本数据类型

(四)IO流——对象流、打印流

其实常用System.out.println输出语句就是一个打印流的println方法

只是创建了PrintStream对象时,指定了File对象,调用print方法时输出的对象变成了文本文件

PrintStream consolePs = System.out;            //用PrintStream对象接受系统输出
PrintStream ps = new PrintStream("b.txt");
System.setOut(ps);                             //设置系统输出流为ps
System.out.println("你好");                    //这个"你好" 会打印在b.txt文本内
System.setOut(consolePs);                      //设置系统输出流为consolePs
System.out.println("你好");                    //这个"你好" 会打印在控制台