저는 파일 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();
}
}
}
나는 Exception이 던져지는 것을 파악하기 위해 모든 개별 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;
}
}
그리고 여기에 파일에 쓰기 기능이 있습니다.
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으로 완료되었습니다.
java.io.StreamCorruptedException: invalid stream header: 0AACED00
이것은 FileOutputStream.
위의 주석에서 언급했듯이에 추가하기 때문에 발생합니다 ObjectOutputStream
. 최소한 특별한 조치 없이는으로 작성된 스트림에 추가 할 수 없습니다 . 파일을 보관 하고ObjectOutputStream
당신이 쓰고 싶은 모든 개체를 작성했습니다 때까지 가까운 그것은, 다음에서 역 직렬화를 엽니 다.
NB 또한 언급했듯이
while ((object = in.readObect()) != null)
유효한 객체 읽기 루프가 아닙니다. readObject()
스트림 끝에서 null을 반환하지 않습니다 EOFException
. null
스트림의 어느 곳에서나 작성할 수 있습니다. 루프의 올바른 형식은 다음과 같습니다.
try
{
for (;;)
{
Object object = in.readObject();
// ...
}
}
catch (EOFException exc)
{
// end of stream
}
// other catch blocks ...
NB 2 이것은 :
oos.writeObject(object + "\n");
그냥
oos.writeObject(object);
그렇지 않으면 암시 적으로 호출 toString()
하고 줄 종결자를 무의미하게 추가하므로 결과 readObject()
는 원래 객체가 아닌 문자열 이 됩니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다