【发布时间】:2018-04-04 11:41:16
【问题描述】:
我有一个使用 memento 设计模式的程序,并希望使用序列化将每个对象的状态保存到一个文件中并返回该对象。问题是由于标头损坏,我收到“java.io.StreamCorruptedException:无效类型代码:AC”异常。我查看了Appending to an ObjectOutputStream 并尝试实现该类,但仍然无法让程序正常工作。多个对象应该保存在一个文件中,并且用户将一个字符串传递给一个函数,该函数应该匹配对象的字符串表示的一部分。
public class Caretaker implements Serializable {
public void addMemento(Memento m) {
try {
// write object to file
FileOutputStream fos = new FileOutputStream("ConeOutput1.txt", true);
BufferedOutputStream outputBuffer = new BufferedOutputStream(fos);
AppendableObjectOutputStream objectStream = new AppendableObjectOutputStream(outputBuffer);
objectStream.writeObject(m);
objectStream.reset();
objectStream.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public Memento getMemento(String temp) {
try {
Memento result = null;
FileInputStream fis = new FileInputStream("ConeOutput1.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
result = (Memento) ois.readObject();
while (result != null) {
Matcher m = Pattern.compile(temp).matcher(result.toString());
if (m.find()) {
return result;
}
else {
result = (Memento) ois.readObject();
}
ois.close();
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
public class AppendableObjectOutputStream extends ObjectOutputStream {
public AppendableObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
@Override
protected void writeStreamHeader() throws IOException {}
}
【问题讨论】:
-
您正在使用一个自定义输出流,它跳过了流标头的写入。但是您没有使用跳过读取流标头的自定义输入流。
-
@JBNizet 否。仅追加时跳过流标头。输入端不需要知道它:它看到整个流就好像在没有附加的情况下写入一样。
-
@Zabuza 问题是关于 ObjectOutputStreams。 NIO 中没有等价物,也没有理由介绍这个无关紧要的话题。请阅读问题。
-
@EJP 为什么你认为它是在第一次写入之前写入标题?流标头由 writeStreamHeader() 写入,由 OubjectOutputStream 构造函数调用,该方法被覆盖不做任何事情。所以永远不会写入流头。
-
@JBNizet 我没有。他不是,这就是问题。流看起来像是一次性编写的,在它的中间没有标题,所以它
ObjectInputStream可以毫不费力地阅读这就是本课程的全部目的。从文件的开头隐藏标题不会完成任何有用的事情,使用特殊类来读取它也不会。
标签: java