3

I have a method that writes data from a list to a file, a method that reads data from a file into a list and a method that writes data from a list in a file to the specified number of times. I'm trying to extract data from a file after I use the first method writeFile () everything works fine. I read the data from the file into the list by readFile () method. After that I use my method which writes to the file the number of times I need, everything is fine, it writes multyWrite (). But after that I can not read the data from the file in the readFile () method since I get `

Exception stack trace:

 Exception in thread "main" java.io.StreamCorruptedException: invalid type code: AC     
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1599)   
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)      
at ProductService.readFile(ProductService.java:47)  
at Main.main(Main.java:21)

I know that I should use objectOutputStream.reset (), but where would it be better to use it?

private String fileName;
    private ProductInterface<FlyingMachine> productService = new ProductInterfaceImpl();
    private ObjectOutputStream objectOutputStream;
    private FileOutputStream fileOutputStream;


    public ProductService(String fileName) throws IOException {
        this.fileName = fileName;
        fileOutputStream = new FileOutputStream(fileName);
        this.objectOutputStream = new ObjectOutputStream(fileOutputStream);
    }

public void writeFile() throws IOException {
        try {
            for (FlyingMachine f : productService.getProductContainer()) {
                objectOutputStream.writeObject(f);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (objectOutputStream != null) {
                objectOutputStream.flush();
                objectOutputStream.close();
                fileOutputStream.close();
            }
        }
    }`

public void readFile() throws IOException {
        ObjectInputStream objectInputStream = null;
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(fileName);
            objectInputStream = new ObjectInputStream(fileInputStream);
            while (fileInputStream.available() > 0) {
                FlyingMachine flyingMachine = (FlyingMachine) objectInputStream.readObject();
                productService.getProductContainer().add(flyingMachine);
            }
        } catch (ClassNotFoundException | EOFException e) {
            e.printStackTrace();
        } finally {
            if (objectInputStream != null) {
                objectInputStream.close();
                fileInputStream.close();
            }
        }
    }

public void multyWrite(int number) throws IOException {
        for (int i = 0; i < number; i++) {
            try {
                fileOutputStream = new FileOutputStream(fileName, true);
                objectOutputStream = new ObjectOutputStream(fileOutputStream);
                for (FlyingMachine f : productService.getProductContainer()) {
                    objectOutputStream.writeObject(f);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (objectOutputStream != null) {
                    objectOutputStream.flush();
                    objectOutputStream.close();
                }
            }
        }
    }
3
  • 1
    Without the complete stacktrace it's hard to figure out. But may be stackoverflow.com/questions/2393179/… helps you. Commented Aug 25, 2018 at 13:40
  • Don't use available() like that. It does not do what you think it does. Commented Aug 25, 2018 at 13:48
  • If I do not use available (), I get EOFException Commented Aug 25, 2018 at 13:54

1 Answer 1

1

You create a new ObjectOutputStream in the constructor. In writeFile you use that OOS instance and close it. But in multyWrite you don't use it and instead create new instances.

Now when you call multyWrite without having called writeFile first, that first OOS will still be open, but the OOS you create in multyWrite doesn't know that - thus causing your file to have two OOS headers after another.

And then when you try to read such a file, the ObjectInputStream will find the first header (all is fine) and then unexpectedly find the second header, while it expected a type code. That header starts with 0xAC, hence throwing the exception message "invalid type code: AC".

To fix this, either have multyWrite use the OOS constructed in your constructor, the same way writeFile does, or make sure that that OOS is closed before you create a new one.

It's generally not a good idea to open a stream (of any kind) in a constructor and then rely on external code calling a specific method to close it. Better create streams when you need them and close them directly.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.