Serialization:java.io.StreamCorruptedException: 无效流 header: 0AACED00
Serialization:java.io.StreamCorruptedException: invalid stream header: 0AACED00
我是一名练习文件 IO 技能的学生,我遇到了使用 ObjectInputStream 从文件读取 Objects 的问题。该代码始终抛出 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();
}
}
}
我编写了所有单独的 catch 块来找出抛出的异常,它总是抛出 InvalidClassException。
这也是我的树 Class:
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;
}
}
这是我的写入文件功能:
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;
}
感谢您的知识...
堆栈跟踪:
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)
进程已完成,退出代码为 0
我认为这是由于缺少 serialVersionUID
。
每当您序列化一个对象时,ClassLoader 都需要一些东西来验证新加载的对象,以验证它并确保其兼容性。为此,您只需在 class 中定义一个字段,如下所示:
private static final long serialVersionUID = 12358903454875L;
您的 IDE 可能也给了您一个警告,说明缺少它(Eclipse 会这样做)。
这应该可以解决您的问题。
您可以在 Jon Skeet 的精彩回答中了解更多信息:What is a serialVersionUID and why should I use it?。
java.io.StreamCorruptedException: invalid stream header: 0AACED00
这是由追加到 FileOutputStream.
引起的 正如我在上面的评论中提到的,您不能追加到 ObjectOutputStream
编写的流,至少在没有特殊措施的情况下是这样。保持文件 和 和 ObjectOutputStream
打开,直到你写完所有你想写的对象,然后关闭它,然后从它反序列化。
注意正如我也提到的,
while ((object = in.readObect()) != null)
不是有效的对象读取循环。 readObject()
在流的末尾 return 不为空:它抛出 EOFException
。 null
可以出现在流中的任何地方,任何时候你写一个。循环的正确形式是:
try
{
for (;;)
{
Object object = in.readObject();
// ...
}
}
catch (EOFException exc)
{
// end of stream
}
// other catch blocks ...
注意 2 这个:
oos.writeObject(object + "\n");
应该只是
oos.writeObject(object);
否则你会隐式调用 toString()
并毫无意义地附加一个行终止符,因此 readObject()
的结果将是一个字符串,而不是原始对象。
我是一名练习文件 IO 技能的学生,我遇到了使用 ObjectInputStream 从文件读取 Objects 的问题。该代码始终抛出 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();
}
}
}
我编写了所有单独的 catch 块来找出抛出的异常,它总是抛出 InvalidClassException。
这也是我的树 Class:
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;
}
}
这是我的写入文件功能:
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;
}
感谢您的知识...
堆栈跟踪:
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)
进程已完成,退出代码为 0
我认为这是由于缺少 serialVersionUID
。
每当您序列化一个对象时,ClassLoader 都需要一些东西来验证新加载的对象,以验证它并确保其兼容性。为此,您只需在 class 中定义一个字段,如下所示:
private static final long serialVersionUID = 12358903454875L;
您的 IDE 可能也给了您一个警告,说明缺少它(Eclipse 会这样做)。
这应该可以解决您的问题。
您可以在 Jon Skeet 的精彩回答中了解更多信息:What is a serialVersionUID and why should I use it?。
java.io.StreamCorruptedException: invalid stream header: 0AACED00
这是由追加到 FileOutputStream.
引起的 正如我在上面的评论中提到的,您不能追加到 ObjectOutputStream
编写的流,至少在没有特殊措施的情况下是这样。保持文件 和 和 ObjectOutputStream
打开,直到你写完所有你想写的对象,然后关闭它,然后从它反序列化。
注意正如我也提到的,
while ((object = in.readObect()) != null)
不是有效的对象读取循环。 readObject()
在流的末尾 return 不为空:它抛出 EOFException
。 null
可以出现在流中的任何地方,任何时候你写一个。循环的正确形式是:
try
{
for (;;)
{
Object object = in.readObject();
// ...
}
}
catch (EOFException exc)
{
// end of stream
}
// other catch blocks ...
注意 2 这个:
oos.writeObject(object + "\n");
应该只是
oos.writeObject(object);
否则你会隐式调用 toString()
并毫无意义地附加一个行终止符,因此 readObject()
的结果将是一个字符串,而不是原始对象。