这几天做一个小的聊天项目用到对象序列化的知识,发现对象序列化不能像普通文件一样直接追加对象。每次写入对象都会被覆盖。弄了2个多小时终于解决了。
Java默认的对象序列化是每次写入对象都会写入一点头aced 0005(占4个字节),然后每次读取都读完头然后在读内容。解决方法就是先判断文件是否存在。如果不存在,就先创建文件。然后写了第一个对象,也写入了头aced 0005。追加的情况就是当判断文件存在时,把那个4个字节的头aced 0005截取掉,然后在把对象写入到文件。这样就实现了对象序列化的追加。代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
String filename=m.getGetter()+m.getSender();
File file=
new
File(
"D:\\"
+filename+
".txt"
);
if
(file.exists()){
isexist=
true
;
FileOutputStream fo=
new
FileOutputStream(file,
true
);
ObjectOutputStream oos =
new
ObjectOutputStream(fo);
long
pos=
0
;
if
(isexist){
pos=fo.getChannel().position()-
4
;
fo.getChannel().truncate(pos);
}
oos.writeObject(m);
//进行序列化
}
else
{
//文件不存在
file.createNewFile();
FileOutputStream fo=
new
FileOutputStream(file);
ObjectOutputStream oos =
new
ObjectOutputStream(fo);
oos.writeObject(m);
//进行序列化
}
下面是系列化的实现。注意要在循环外面关闭流,在里面关闭会出现句柄无效的错误。
String fileName=owner+friendNo;
File file =
new
File(
"D:"
+File.separator+fileName+
".txt"
);
if
(file.exists()){
ObjectInputStream ois;
try
{
FileInputStream fn=
new
FileInputStream(file);
ois =
new
ObjectInputStream(fn);
while
(fn.available()>
0
){
//代表文件还有内容
Message p = (Message)ois.readObject();
//从流中读取对象
System.out.println(p.getCon);
}
ois.close();
//注意在循环外面关闭
}
catch
(Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
|