五、对象流的使用
-
ObjectInputStream 和 ObjectOutputStream
-
作用:用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。
-
要想一个Java对象是可序列化的,需要满足相应的要求。
-
需要实现接口:Serializable
-
当前类提供一个全局常量:serialVersionUID 序列版本号
凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态常量:private static final long serialVersionUID;
serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。
如果类没有显示定义这个静态常量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议,显式声明。
-
除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型可序列化)
-
-
ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量
(面试题)序列化机制
允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点;
当其他程序获取了这种二进制流,就可以恢复成原来的Java对象
序列化过程
将内存中的Java对象保存到磁盘中或通过网络传输出去
使用 ObjectInputStream 实现
@Test
public void test5() {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(new File("object.dat")));
oos.writeObject(new String("我爱北京天安门"));
oos.flush(); // 刷新操作
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(oos != null) {
oos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
反序列化
将磁盘文件中的对象还原为内存中的一个Java对象
使用 ObjectOutputStream 来实现
@Test
public void test32() {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(new File("object.dat")));
Object obj = ois.readObject();
String str = (String) obj;
System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
六、RandomAccessFile的使用
-
RandomAccessFile直接继承于java.lang.Object类,实现了DataInput和DataOutput接口
-
RandomAccessFile既可以作为一个输入流,又可以作为一个输出流
-
如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建
如果写出到的文件存在,则会对原有文件内容进行覆盖。(默认情况下,从头覆盖)
使用RandomAccessFile实现数据的插入效果
@Test
public void test50() throws IOException {
RandomAccessFile raf = new RandomAccessFile(new File("hello.txt"),"rw");
raf.seek(3); // 将指针调到角标为3的位置
// 保存指针3后面的所有数据到StringBuilder中
StringBuilder builder = new StringBuilder((int)new File("hello.txt").length());
byte[] buffer = new byte[20];
int len;
while((len = raf.read(buffer)) != -1) {
builder.append(new String(buffer,0,len));
}
// 调回指针,写入"xyz"
raf.seek(3);
raf.write("xyz".getBytes());
// 将StringBuilder中的数据写入到文件中
raf.write(builder.toString().getBytes());
raf.close();
}