反序列化问题
Issue with Deserialization
我的程序中有一个方法可以从文件中读取数据,并且我已经关联了一个 FileInputStream 变量和一个 ObjectInputStream 变量。但是,我不知道当我运行程序时文件中将序列化多少个对象,所以我不知道使用方法readObject()反序列化多少个对象。这是我项目中的方法:
public void importResults(File file) throws FileNotFoundException, IOException, ClassNotFoundException {
TestEntry entry = null;
try(FileInputStream fis = new FileInputStream(file)) {
ObjectInputStream ois = new ObjectInputStream(fis);
tests.clear();
entry = (TestEntry)ois.readObject();
tests.add(entry);
ois.close();
}
}
变量 entry 是我将存储从文件中反序列化的 TestEntry 对象的地方。问题是,如果我尝试反序列化太多对象,我会得到 EOFException。我如何让我的程序找出文件中序列化了多少个对象,以便我可以反序列化正确的数量?任何帮助将不胜感激!谢谢。
我不认为有一种方法可以计算有多少对象被序列化,因为一个文件只能容纳一个对象。您可能会收到 EOFException,因为您正在执行如下所示的操作。因为无论你序列化多少,一个文件中只有一个对象,从同一个流读取两次将导致 EOFException。
in.readObject();
in.readObject();
我刚刚测试过,只要您不执行上述操作或类似操作,您就可以从同一个文件中多次读取一个对象。
下面是我的测试
public static void main(String []args) {
writeObject(new Integer(333));
for(int i = 0; i < 9999; i++) {
Integer i = (Integer)readObject();
System.out.println(i);//prints 333
}
}
public static void writeObject(Object obj) {
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("file.dat"));
out.writeObject(obj);
out.close();
}
catch(IOException e) {}
}
public static Object readObject() {
Object obj = null;
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("file.dat"));
obj = in.readObject();
in.close();
}
catch(IOException e){}
catch(ClassNotFoundException e){}
return obj;
}
也许你可以写下文件中存在的对象数量,然后在反序列化时首先读取该数字(但我不确定一个文件是否可以包含多个序列化对象)。
但是,如果您将对象放入序列化的 ArrayList
中,则可以将 ArrayList
写入文件并通过读取 one[=21= 来反序列化它] 对象。
我做了一个测试 class A
并且有效:
public class A implements Serializable {
int a, b, c;
}
public static ArrayList<A> deserializeObjects(File file) throws FileNotFoundException, IOException, ClassNotFoundException {
FileInputStream fIn = new FileInputStream(file);
ObjectInputStream oIn = new ObjectInputStream (fIn);
ArrayList<A> objects = null;
// Read array of objects
if(fIn.available() > 0) {
objects = (ArrayList<A>) oIn.readObject();
}
oIn.close();
fIn.close();
return objects;
}
public static void serializeObjects(File file, ArrayList<A> objects) throws IOException {
FileOutputStream fOut = new FileOutputStream(file);
ObjectOutputStream oOut = new ObjectOutputStream(fOut);
// Write the whole arraylist to file
oOut.writeObject(objects);
oOut.flush();
oOut.close();
fOut.close();
}
public static void main(String args[]) throws IOException, ClassNotFoundException {
// Make test objects
A o1 = new A();
A o2 = new A();
o1.a = 1; o1.b = 2; o1.c = 3;
o2.a = 4; o2.b = 5; o2.c = 6;
ArrayList<A> objects = new ArrayList<A>();
objects.add(o1);
objects.add(o2);
File f = new File("yourFile");
f.createNewFile();
serializeObjects(f, objects); // Serialize arraylist
ArrayList<A> deserialized = deserializeObjects(f); // Deserialize it
// Success??
System.out.println("a : " + deserialized.get(0).a + ", b : " + deserialized.get(0).b + ", c : " + deserialized.get(0).c);
System.out.println("a : " + deserialized.get(1).a + ", b : " + deserialized.get(1).b + ", c : " + deserialized.get(1).c);
}
您可以将对象添加到列表中,然后 serialize/deserialize 该列表。
// entry = (TestEntry)ois.readObject();
List<TestEntry> entries = (List<TestEntry>)ois.readObject();
只是循环读取,直到得到 EOFException,
,当没有更多对象可读取时抛出。
我的程序中有一个方法可以从文件中读取数据,并且我已经关联了一个 FileInputStream 变量和一个 ObjectInputStream 变量。但是,我不知道当我运行程序时文件中将序列化多少个对象,所以我不知道使用方法readObject()反序列化多少个对象。这是我项目中的方法:
public void importResults(File file) throws FileNotFoundException, IOException, ClassNotFoundException {
TestEntry entry = null;
try(FileInputStream fis = new FileInputStream(file)) {
ObjectInputStream ois = new ObjectInputStream(fis);
tests.clear();
entry = (TestEntry)ois.readObject();
tests.add(entry);
ois.close();
}
}
变量 entry 是我将存储从文件中反序列化的 TestEntry 对象的地方。问题是,如果我尝试反序列化太多对象,我会得到 EOFException。我如何让我的程序找出文件中序列化了多少个对象,以便我可以反序列化正确的数量?任何帮助将不胜感激!谢谢。
我不认为有一种方法可以计算有多少对象被序列化,因为一个文件只能容纳一个对象。您可能会收到 EOFException,因为您正在执行如下所示的操作。因为无论你序列化多少,一个文件中只有一个对象,从同一个流读取两次将导致 EOFException。
in.readObject();
in.readObject();
我刚刚测试过,只要您不执行上述操作或类似操作,您就可以从同一个文件中多次读取一个对象。
下面是我的测试
public static void main(String []args) {
writeObject(new Integer(333));
for(int i = 0; i < 9999; i++) {
Integer i = (Integer)readObject();
System.out.println(i);//prints 333
}
}
public static void writeObject(Object obj) {
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("file.dat"));
out.writeObject(obj);
out.close();
}
catch(IOException e) {}
}
public static Object readObject() {
Object obj = null;
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("file.dat"));
obj = in.readObject();
in.close();
}
catch(IOException e){}
catch(ClassNotFoundException e){}
return obj;
}
也许你可以写下文件中存在的对象数量,然后在反序列化时首先读取该数字(但我不确定一个文件是否可以包含多个序列化对象)。
但是,如果您将对象放入序列化的 ArrayList
中,则可以将 ArrayList
写入文件并通过读取 one[=21= 来反序列化它] 对象。
我做了一个测试 class A
并且有效:
public class A implements Serializable {
int a, b, c;
}
public static ArrayList<A> deserializeObjects(File file) throws FileNotFoundException, IOException, ClassNotFoundException {
FileInputStream fIn = new FileInputStream(file);
ObjectInputStream oIn = new ObjectInputStream (fIn);
ArrayList<A> objects = null;
// Read array of objects
if(fIn.available() > 0) {
objects = (ArrayList<A>) oIn.readObject();
}
oIn.close();
fIn.close();
return objects;
}
public static void serializeObjects(File file, ArrayList<A> objects) throws IOException {
FileOutputStream fOut = new FileOutputStream(file);
ObjectOutputStream oOut = new ObjectOutputStream(fOut);
// Write the whole arraylist to file
oOut.writeObject(objects);
oOut.flush();
oOut.close();
fOut.close();
}
public static void main(String args[]) throws IOException, ClassNotFoundException {
// Make test objects
A o1 = new A();
A o2 = new A();
o1.a = 1; o1.b = 2; o1.c = 3;
o2.a = 4; o2.b = 5; o2.c = 6;
ArrayList<A> objects = new ArrayList<A>();
objects.add(o1);
objects.add(o2);
File f = new File("yourFile");
f.createNewFile();
serializeObjects(f, objects); // Serialize arraylist
ArrayList<A> deserialized = deserializeObjects(f); // Deserialize it
// Success??
System.out.println("a : " + deserialized.get(0).a + ", b : " + deserialized.get(0).b + ", c : " + deserialized.get(0).c);
System.out.println("a : " + deserialized.get(1).a + ", b : " + deserialized.get(1).b + ", c : " + deserialized.get(1).c);
}
您可以将对象添加到列表中,然后 serialize/deserialize 该列表。
// entry = (TestEntry)ois.readObject();
List<TestEntry> entries = (List<TestEntry>)ois.readObject();
只是循环读取,直到得到 EOFException,
,当没有更多对象可读取时抛出。