0

I am attempting to save multiple objects into a file by running the code multiple times. But in the second run, I get a java.io.StreamCorruptedException error.

package BinaryIO;

import java.io.*;

public class OOSDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        File file = new File("src/BinaryIO/robotData.dat");
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file, true))) {
            oos.writeObject(new Robot());
            oos.flush();
        }
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
            while (true) {
                try {
                    System.out.println(ois.readObject().toString());
                } catch (EOFException e) {
                    break;
                }
            }
        }
    }
}

class Robot implements Serializable {
    int x, y;
    String model;

    public Robot() {
        this(0, 0, "Default");
    }

    public Robot(int x, int y, String model) {
        this.x = x;
        this.y = y;
        this.model = model;
    }

    @Override
    public String toString() {
        return String.format("Robot: (%d, %d), Model: %s", x, y, model);
    }
}

Error in the second run:

Robot: (0, 0), Model: Default
Exception in thread "main" java.io.StreamCorruptedException: invalid type code: AC
    at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1743)
    at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:519)
    at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:477)
    at BinaryIO.OOSDemo.main(OOSDemo.java:14)

I am not able to identify the problem. On online forums, it says that the error could occur if:

  1. you try to open an ObjectInputStream around some data that wasn't actually written using an ObjectOutputStream;
  2. during a readObject() operation, the stream gets in the "wrong place". [Source]
Shiv Patel
  • 114
  • 7
  • Please include your full stack trace and indicate which line of code triggered the error (Was it this part `ois.readObject().toString()`?) – sorifiend Apr 15 '21 at 22:25
  • 1
    You didn't close or flush the output stream, not all the data may have been written by the time you opened it for input. – Jim Garrison Apr 15 '21 at 22:26
  • @sorifiend Yes. I have updated the question. – Shiv Patel Apr 15 '21 at 22:29
  • @Jim Garrison I tried doing that. Still getting an error. – Shiv Patel Apr 15 '21 at 22:30
  • @ShivPatel Closing the stream correctly should solve your issue. Updated your question to show how you are using flush and close on the output stream and how you are closing your input steam. – sorifiend Apr 15 '21 at 22:34
  • Remove `, true`. You **cannot append** to an `ObjectOutputStream`. – Andreas Apr 15 '21 at 22:38
  • @JimGarrison Unless the question was edited in the first 5 minutes, where it doesn't show as an edit, the question has always flushed and closed the `ObjectOutputStream` correctly, by using *try-with-resources*, and done so before opening the `ObjectInputStream`. – Andreas Apr 15 '21 at 22:40
  • @Andreas Why not? https://forums.codeguru.com/showthread.php?393986-ObjectOutputStream-APPEND#:~:text=Yes%20you%20can%20do%20this,to%20it%20as%20you%20like. – Shiv Patel Apr 15 '21 at 22:43
  • @sorifiend *"how you are using flush and close"* See try-with-resources: `try (...) { ... }`. The `}` does the flushing and closing. – Andreas Apr 15 '21 at 22:43
  • 2
    @ShivPatel Because: [Appending to an ObjectOutputStream](https://stackoverflow.com/q/1194656/5221149) --- When I said you cannot append, I meant to say that you'd need to jump through extra hoops to make that work. Since you're not, appending won't work for you. And those extra hoops is a hack. – Andreas Apr 15 '21 at 22:45
  • @ShivPatel And of course: If the `robotData.dat` file got corrupted in an earlier test, appending to it will not fix the corruption, so the file needs to be deleted to get rid of that. – Andreas Apr 15 '21 at 22:49
  • @Andreas I tried deleting the file and running the code again. It doesn't work. I still don't get why we cannot append the file using OOS. If we are allowed to save multiple objects in a file by using writeObject() multiple times in a single run. Then, how is it different from appending to the file? Is there a different mechanism involved in both cases? – Shiv Patel Apr 15 '21 at 22:54
  • 2
    @ShivPatel Perhaps if you actually read the answers I linked to, you'd know. To re-cap: OOS writes a **header** before the first object. When you append, a new header is written, and OIS will fail to read that. – Andreas Apr 15 '21 at 22:58

0 Answers0