首页 > 解决方案 > 如何避免 java.io.StreamCorruptedException?

问题描述

我有一种将数据从列表写入文件的方法,一种将数据从文件读取到列表的方法,以及一种将数据从文件中的列表写入指定次数的方法。使用第一种方法后,我正在尝试从文件中提取数据,writeFile ()一切正常。我通过方法将文件中的数据读入列表中readFile ()。之后,我使用我需要的次数写入文件的方法,一切都很好,它写道multyWrite ()。但是在那之后我无法从readFile ()方法中的文件中读取数据,因为我得到了`

异常堆栈跟踪:

 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)

我知道我应该使用objectOutputStream.reset (),但是在哪里使用它会更好?

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();
                }
            }
        }
    }

标签: java

解决方案


您在构造函数中创建一个新ObjectOutputStream的。在writeFile您使用该OOS实例并关闭它时。但是multyWrite你不要使用它,而是创建新的实例。

现在,当您在没有先调用multyWrite的情况下调用时writeFile,第一个OOS仍然是打开的,但是OOS您创建的multyWrite并不知道 - 从而导致您的文件有两个OOS接一个的标题。

然后当您尝试读取这样的文件时,ObjectInputStream将找到第一个标头(一切都很好),然后意外找到第二个标头,而它需要一个类型代码。该标头以 开头0xAC,因此抛出异常消息"invalid type code: AC"

要解决此问题,要么multyWrite使用OOS构造函数中的构造,以同样的方式writeFile,要么确保OOS在创建新构造之前将其关闭。

在构造函数中打开(任何类型的)流然后依赖外部代码调用特定方法来关闭它通常不是一个好主意。在需要时更好地创建流并直接关闭它们。


推荐阅读