序列化:java.io.StreamCorruptedException:无效的流标题:0AACED00

Ple*_*her 6 java serialization java-io

我是一名学习我的文件IO技能的学生,我遇到了使用ObjectInputStream从文件中读取对象的问题.代码一直抛出一个InvalidClassException,我无法找到代码是如何在线投掷或通过反复试验.这是我的代码:

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class ReadFromFile {
String filename;
List<Object> os;

public ReadFromFile(String filename) {
    this.filename = filename;
    os = new ArrayList<>();
}

public Object[] readObject() {
    try {
        FileInputStream fis = new FileInputStream(filename);
        ObjectInputStream ois = new ObjectInputStream(fis);
        System.out.print("reading\n");
        while (true) {
            os.add(ois.readObject());
            System.out.print("read one\n");
        }
    } catch (EOFException e) {
        return os.toArray();
    } catch (FileNotFoundException e) {
        System.out.print("File not found\n");
        return os.toArray();
    } catch (ClassNotFoundException e) {
        System.out.print("Class not found\n");
        return os.toArray();
    } catch (StreamCorruptedException e) {
        System.out.print("SC Exception\n");
        e.printStackTrace();
        return os.toArray();
    } catch (InvalidClassException e) {
        e.printStackTrace();
        System.out.print("IC Exception\n");
        return os.toArray();
    } catch (OptionalDataException e) {
        System.out.print("OD Exception\n");
        return os.toArray();
    } catch (IOException e) {
        System.out.print("IO Exception\n");
        return os.toArray();
    }
}
} 
Run Code Online (Sandbox Code Playgroud)

我写了所有单独的catch块来弄清楚抛出了什么异常,它总是抛出InvalidClassException.

这也是我的树类:

import java.io.Serializable;

public class Tree implements Serializable {
private static final long serialVersionUID = -310842754445106856L;
String species;
int age;
double radius;

public Tree() {
    this.species = null;
    this.age = 0;
    this.radius = 0;
}
public Tree(String species, int age, double radius) {
    this.species = species;
    this.age = age;
    this.radius = radius;
}

public String toString() {
    return species + ", age: " + age + ", radius: " + radius;
}
}
Run Code Online (Sandbox Code Playgroud)

这是我写的文件功能:

public boolean write(Object object) {
    try {
        File f = new File(filename);
        FileOutputStream fos = new FileOutputStream(f,true);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(object + "\n");
        oos.close();
    } catch (FileNotFoundException e) {
        System.out.print("File Not Found\n");
        return false;
    } catch (IOException e) {
        System.out.print("IOException\n");
        return false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

感谢您的知识......

堆栈跟踪:

SC Exception
java.io.StreamCorruptedException: invalid stream header: 0AACED00
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:806)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at ReadFromFile.readObject(ReadFromFile.java:17)
at WriteAndRecord.main(WriteAndRecord.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Run Code Online (Sandbox Code Playgroud)

进程以退出代码0结束

use*_*421 4

 java.io.StreamCorruptedException: invalid stream header: 0AACED00 
Run Code Online (Sandbox Code Playgroud)

这是由于附加到FileOutputStream.正如我在上面的评论中提到的,您不能附加到由 编写的流ObjectOutputStream,至少在没有特殊措施的情况下不能附加。保持文件处于打开状态ObjectOutputStream,直到写入所有要写入的对象,然后关闭它,然后从中反序列化。

注意正如我也提到的,

while ((object = in.readObect()) != null)
Run Code Online (Sandbox Code Playgroud)

不是有效的对象读取循环。readObject()在流末尾不返回 null:它会抛出EOFException. null可以在流中的任何位置发生,无论您何时编写。循环的正确形式是:

try
{
    for (;;)
    {
        Object object = in.readObject();
        // ...
    }
}
catch (EOFException exc)
{
    // end of stream
}
// other catch blocks ...
Run Code Online (Sandbox Code Playgroud)

注意 2 这个:

oos.writeObject(object + "\n");
Run Code Online (Sandbox Code Playgroud)

应该是公正的

oos.writeObject(object);
Run Code Online (Sandbox Code Playgroud)

否则,您将隐式调用toString()并毫无意义地附加行终止符,因此结果readObject()将是一个字符串,而不是原始对象。