在文件末尾追加对象
用对象流写到文件中时,首先会将对象信息写到文件头才开始写具体数据.每次追加的时候也是同样.这就造成了之后读取文件的时候无法正常读取.
java帮我们读的时候只会过滤掉第一次的头部信息,之后的它没法识别.
解决办法有二:
文件较小的时候,不追加.可以先读出所有的对象,将要追加的加在后面再重新写一遍.(文件更小)
文件较大的时候,直接在后面追加.跳过头部信息不写出去了.(效率更高)
public static void read(String str) {
File file = new File(str);
try {
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
User us = (User) ois.readObject();
while (us != null) {
Server.allUser.put(us.num, us);
us = (User) ois.readObject();
}
ois.close();
System.out.println(Server.allUser);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void saveAll(String str) {
File file = new File(str);
try {
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
Set<Integer> set = Server.allUser.keySet();
for (int i : set) {
oos.writeObject(Server.allUser.get(i));
}
oos.flush();
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
如上面这两个方法,一个是读取文件中的User对象,一个是将User写到文件中.这个无需过多解释
再看之后的追加办法:
public static void save(String str, User user) {
File file = new File(str);
try {
FileOutputStream fos = new FileOutputStream(file, true);
MyObjectWrite oos = new MyObjectWrite(fos);
// 由于需要在static中创建,所以MyObjectWrite为static
oos.writeObject(user);
oos.flush();
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 重写对象输出流,不让它写头文件
*
* @author Huangbin
*
*/
static class MyObjectWrite extends ObjectOutputStream {
public MyObjectWrite(OutputStream out) throws IOException {
super(out);// 会调用writeStreamHeader()
}
@Override
protected void writeStreamHeader() throws IOException {
super.reset();
}
}
new FileOutputStream(file, true);
true表示是追加.
这里我们要重写ObjectOutputStream中的writeStreamHeader方法.
因为ObjectOutputStream在writeObject的时候回调用这个方法写头信息.我们重写这个方法,不让它写头信息.这样就实现了目的了.
将 super.reset();改为super.writeStreamHeader();就会写头信息了.