0

I have a program utilizing the memento design pattern and want to save the state of each object into a file using serialization and return the object back. The problem is that I get a "java.io.StreamCorruptedException: invalid type code: AC" exception due to corrupt headers. I looked at Appending to an ObjectOutputStream and tried to implement the class but still can't get the program to work properly. Multiple objects should be saved in a file and the user passes a string into a function which should match part of the object's string representation.

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 {}

}

  • You're using a custom output stream that skips the writing of the stream header. But you're not using a custom input stream that skips the reading of the stream header. – JB Nizet Oct 23 '17 at 20:17
  • @JBNizet No. The stream header is skipped when appending only. The input side doesn't need to know about it: it sees the whole stream as though written without appending. – user207421 Oct 23 '17 at 20:22
  • @Zabuza The question is about ObjectOutputStreams. There is no equivalent in NIO, and no reason to introduce this irrelevant topic. Please read the question. – user207421 Oct 23 '17 at 20:24
  • @EJP why do you think it's writing the header before the first write? The stream header is written by writeStreamHeader(), which is called by the OubjectOutputStream constructor, and the method is overridden to do nothing. So the stream header is never written. – JB Nizet Oct 23 '17 at 20:25
  • @JBNizet I don't. He isn't, and that's the *problem.* The stream is meant to look like it was written in a single go, without headers in the *middle* of it, so that it can be read by an `ObjectInputStream` without further ado That's the whole purpose of the class. Suppressing the header from the start of the file doesn't accomplish anything useful, and neither does using a special class to read it. – user207421 Oct 23 '17 at 20:29
  • @EJP No. There is no problem in never writing the stream header if you make sure to never read it. You just need to be symmetric, and read what you write. https://ideone.com/K0PXbS. That seems easier to me than making a special case for the first write. And it's easier to understand, too, IMHO, since it's symmetric. – JB Nizet Oct 23 '17 at 20:37
  • @JBNizet It is just as easy to argue that It is easier not to write a special class for reading. – user207421 Oct 24 '17 at 01:44

1 Answers1

0

You should only use the appending ObjectOutputStream if the file already exists with data in it. If the file is new it needs the object stream header.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Made the changes to check if the file already exists, works fine now. Is there a way to clear the contents of the file so i'm not continuously appending to the file? For example "vanilla, chocolate, strawberry" gets appended to the file every time I run the program. –  Oct 23 '17 at 22:49
  • 1
    Eh? If you don't want to append, **don't append. ** – user207421 Oct 24 '17 at 01:45