您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
javase第三季学习笔记-IO之对象流
发布时间:2017-08-10 14:31:50编辑:雪饮阅读()
对象序列化
对象序列化就是指将一个对象转化成二进制的byte流
两种情况:
将对象保存在文件上的操作称为对象的序列化操作
将对象从文件之中恢复称为反序列化的操作
使用ObjectOutputStream类实现对象的序列化,使用ObjectInputStream类实现反序列。
被序列化对象所在的类必须实现java.io.Serializable接口
ObjectOutputStream
public class ObjectOutputStream extends OutputStream
implements ObjectOutput,ObjectStreamConstants
ObjectOutputStream将java对象的基本数据类型和图形写入OutputStream
ObjectInputStream
public class ObjectInputStream extends InputStream
implementsObjectInput,ObjectStreamConstants
ObjectInputStream对以前使用ObjectOutputStream写入的基本数据和对象进行反序列化。
示例代码:写入到文件
主程序:ObjectStreamDemo.java
package com.vince.objectstream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class ObjectStreamDemo {
//使用ObjectOutputStream把对象写入文件中
public static void writerObject(){
String filePath="E:"+File.separator+"duminjie_love_gaojiupan"+File.separator+"BaiduNetdiskDownload.txt";
try {
OutputStream out = new FileOutputStream(filePath);
//根据字节输出流构造一个对象流
ObjectOutputStream oos=new ObjectOutputStream(out);
//输出数据
//序列化可以向文件中写入不止一种类型数据,还可以多种类型数据同时写入到一个文件中。如下则是又写入了int又写入了object
oos.writeInt(106);
Dog dog=new Dog("小白",8);
oos.writeObject(dog);//向文件写入对象
//关闭流
oos.close();
out.close();
} catch (FileNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
public static void main(String[] args) {
writerObject();
}
}
待序列化对象:Dog所在文件Dog.java
package com.vince.objectstream;
import java.io.Serializable;
//类通过实现java.io.serializable接口以启用其序列化功能
//此接口属于标记接口,没有任何方法
public class Dog implements Serializable {
private String name;
private int age;
public Dog() {
super();
// TODO 自动生成的构造函数存根
}
public Dog(String name, int age) {
super();
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dog [name=" + name + ", age=" + age + "]";
}
}
示例代码:从文件读取
主程序:ObjectStreamDemo.java
package com.vince.objectstream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
public class ObjectStreamDemo {
//使用ObjectInputStream读取文件中的对象
public static void readerObject(){
String filePath="E:"+File.separator+"duminjie_love_gaojiupan"+File.separator+"BaiduNetdiskDownload.txt";
try {
InputStream in = new FileInputStream(filePath);
//根据字节输入流构造一个对象流
ObjectInputStream ois=new ObjectInputStream(in);
//读取一个整数
//如果是多个整数则不能这样读取
int num=ois.readInt();
//读取一个对象
//如果是多个对象则不能这样读取
Dog dog=(Dog)ois.readObject();
ois.close();
in.close();
System.out.println("num="+num);
//直接打印对象则是读取对象的String toString()方法
System.out.println(dog);
} catch (FileNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
public static void main(String[] args) {
readerObject();
}
}
待序列化对象:Dog所在文件Dog.java(和上面一样)
序列化一组对象
在序列化操作中,同时序列化多个对象时,反序列化也必须按顺序操作,如果想要序列化一组对象该如何操作呢?
序列化一组对象可采用:对象数组的形式,因为对象数组可以向Object进行转型操作
序列化时可以一个个序列化,如要序列化3个对象则创建3个对象,并分别对其序列化。
反序列化时也可以一个个反序列化,但是有时候不知道有多少对象被序列化了。则不能一个一个反序列化了,如果反序列化超过了总对象数则会报异常。
对象数组的序列化与反序列化:原Dog.java不变
主程序:objectstream.java
package com.vince.objectstream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class ObjectStreamDemo {
//使用ObjectInputStream读取文件中的对象
public static void readerObject(){
String filePath="E:"+File.separator+"duminjie_love_gaojiupan"+File.separator+"BaiduNetdiskDownload.txt";
try {
InputStream in = new FileInputStream(filePath);
//根据字节输入流构造一个对象流
ObjectInputStream ois=new ObjectInputStream(in);
//读取一个对象
Dog[] dogs=(Dog[])ois.readObject();
ois.close();
in.close();
for (Dog dog : dogs) {
System.out.println(dog);
}
} catch (FileNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
//使用ObjectOutputStream把对象写入文件中
public static void writerObject(){
String filePath="E:"+File.separator+"duminjie_love_gaojiupan"+File.separator+"BaiduNetdiskDownload.txt";
try {
OutputStream out = new FileOutputStream(filePath);
//根据字节输出流构造一个对象流
ObjectOutputStream oos=new ObjectOutputStream(out);
Dog[] dogs={new Dog("小白",8),new Dog("小黑",4),new Dog("小红",2)};
oos.writeObject(dogs);//向文件写入对象
//关闭流
oos.close();
out.close();
} catch (FileNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
public static void main(String[] args) {
writerObject();
readerObject();
}
}
transient关键字
如果用transient声明一个实例变量,当对象存储时,它的值不需要维持
当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。
transient修饰age:
private transient int age;
例如上面示例中的age若被transient修饰,则反序列化时读取age值为0(默认值)。
关键字词:javase,io,对象