【问题标题】:How to read a List of List of Objects from a file using ObjectInputStream in Java?如何使用 Java 中的 ObjectInputStream 从文件中读取对象列表?
【发布时间】:2014-05-30 22:41:27
【问题描述】:

我有一个数据结构中定义的一些对象的列表: 列表 > someObject1=new ArrayList();

我已经使用函数 writeData 将一些对象项写入文件XY:

void writeData(List <List<Integer>> someObject1, File XY) throws IOException {
    try(ObjectOutputStream outFile = new ObjectOutputStream(new FileOutputStream(XY,true)))
    outFile.writeObject(someObject1);
    }
    catch( IOException ex) { ex.printStackTrace(); } 
}

现在我尝试使用函数 readData 读取它:

void readData(File XY) throws IOException {
    try (ObjectInputStream inFile=new ObjectInputStream(new FileInputStream(XY))) {
    List <List <MyClass>> someObject2=(List <List <MyClass>>)inFile.readObject();
    }
catch( IOException ex) { ex.printStackTrace(); } 
}

但它给了我错误:

java.io.OptionalDataException
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1363)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)

谁能帮帮我。读取此数据结构时,转换是否有问题?

如果它只是一个对象列表,我可以通过使用 readObject() 转换来读取它

(List<MyClass>).

为什么同样的事情对对象列表不起作用?

这是 MyClass 的大纲:

public class MyClass implements Serializable {
private long aa;    
private List <Integer> bb;
public MyClass(long a,List <Integer> b) {
    aa=a;
    bb=b;         
}
public long getA() {    
    return aa;
}         

public List<Integer> getB () {
   return bb; 
} 

}

【问题讨论】:

  • 你能把关闭outFile的代码包含进去吗?
  • 能不能把'MyClass'的相关部分也包括进来?它有自定义的 readObject()/writeObject() 方法吗?如果有,请展示给他们看。
  • 写/读后不要忘记关闭ObjectOutputStreamObjectInputStream
  • 你的代码实际上并没有编译。如果您尝试追加到对象流文件,则不能,至少在没有特殊处理的情况下不能,否则您将在文件中间写入重复的流标头。但这通常会导致带有“无效类型代码:AC”的 StreamCorruptedException。并且不关闭文件通常会导致 EOFException。所以我的钱花在了自定义序列化方法中的一些奇怪的东西上。这不可能是演员阵容,因为你还没有做到这一点。
  • @Kaur try 只有在 try-with-resource 这样的情况下才会隐式关闭它:try(stream declaration) { code }

标签: java arraylist io objectinputstream objectoutputstream


【解决方案1】:

这绝对适合我:

public static final String FILE = "file.b";

public static class MyClass implements Serializable {
    private long aa;
    private List<Integer> bb;

    public MyClass(long a, List<Integer> b) {
        aa = a;
        bb = b;
    }
}

public static void main(String[] args) throws FileNotFoundException, IOException,
        ClassNotFoundException {
    List<List<MyClass>> list = new ArrayList<>();
    list.add(new ArrayList<>());
    list.get(0).add(new MyClass(5, new ArrayList<>()));

    ObjectOutputStream outFile = new ObjectOutputStream(new FileOutputStream(new File(FILE)));
    outFile.writeObject(list);
    outFile.close();

    ObjectInputStream inFile = new ObjectInputStream(new FileInputStream(new File(FILE)));
    List<List<MyClass>> list2 = (List<List<MyClass>>) inFile.readObject();
    System.out.println(list2);
}

注意:即使我不添加任何 MyClass list.get(0),即使我不添加列表,这仍然有效到 list

我想到了您的问题的几个可能原因:

  • 写入后忘记关闭输出流
  • 您没有读取文件中正确位置的对象。如果您将多个对象写入文件,则必须按照写入时的顺序读取它们。
  • 您的问题在于您的自定义类

更新:

也许您在可序列化类MyClass 中使用了不可序列化属性。如果是这样,您应该覆盖 writeObject()readObject() 以正确序列化/反序列化您的类的此类属性。

看看这个: http://marxsoftware.blogspot.fr/2014/02/serializing-java-objects-with-non.html

【讨论】:

  • 谢谢@Joffrey。我没有覆盖 writeObject 和 readObject 方法。我在 MyClass 中只使用了 Serializable 接口。
  • @Kaur 我知道你现在还没有覆盖这些方法,但是如果你有不可序列化的属性,如果你想让它工作,你应该这样做。您的自定义类MyClass 中是否还有其他类型的属性?
  • 不,我有一个只有这两个属性的简单类——如上面 cide 中所述。我还需要实现/覆盖 readObject()/writeObject() 方法吗?
  • @Kaur 我不这么认为,因为List 是可序列化的。我更新了适用于你的课程的代码。仍然有效。你的问题一定出在其他地方。
  • 感谢您的努力。我会再看看我的代码。
猜你喜欢
  • 1970-01-01
  • 2013-07-07
  • 1970-01-01
  • 2012-07-31
  • 2013-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多