【问题标题】:Write Multiple objects in a File and Read them在文件中写入多个对象并读取它们
【发布时间】:2014-03-01 10:46:37
【问题描述】:

我正在尝试创建一个带有用户界面的简单程序。来自 gui 的用户插入 Person Implements Serializable 类的姓名、姓氏和年龄。

一切都很好,但只适用于一个人,第一个人!似乎每次我向我的文件发送一个新对象时,它确实会写入文件,因为文件大小越来越大。

问题是,当我读取带有对象的文件时,它只返回一个,我希望返回存储在 myFile 中的 person 类的所有对象。

下面是我的代码的预览:

写入对象按钮:

try {
    per = new Person(name, sur, age);
    FileOutputStream fos = new FileOutputStream("myFile", true);
    ObjectOutputStream oos;
    oos = new ObjectOutputStream(fos);
    oos.writeObject(per);
    oos.flush();
    oos.close();
    //some other code here
} catch (IOException e) {
    //some code here
}

读取对象按钮:

try {
    FileInputStream fis = new FileInputStream("myFile");
    ObjectInputStream ois;
    ois = new ObjectInputStream(fis);
    try {
        rper = (Person) ois.readObject();
        ois.close();
        JOptionPane.showMessageDialog(null, "People:" + rper, "Saved Persons", JOptionPane.INFORMATION_MESSAGE);
    } catch (ClassNotFoundException e) {
        //some code here
    }
} catch (IOException e) {
    //some code here
}

感谢您提供任何信息!

【问题讨论】:

  • 请学习format your code。这个问题会被大多数人忽略,因为它无法阅读。 you 怎么理解它的 your 代码在做什么?
  • @BoristheSpider 我认为它是超基本的,我什至需要评论上面的代码吗?
  • 我在你的代码中看不到任何循环,尽管你的问题是关于写和读多人。
  • @JBNizet 嗯是的,但我怎么知道每个对象的结束位置?
  • 您在 ObjectOutputStream 中一次写入多个对象,然后从 ObjectInputStream 中读取对象,直到您收到异常信号,表明流结束。或者更简单,您将单个 List 写入流,然后从流中读取单个 List

标签: java serialization


【解决方案1】:

每次打开文件时,都会写入一个标题。当输入流阅读器在第一次读取后看到此标头时,它会引发异常。由于您在异常处理中没有任何“printStackTrace”调用,因此您看不到该错误。

修复是为了防止在您打开流时在后续调用中写入标头。通过在打开文件之前检查文件是否存在来做到这一点,如果它已经存在,请使用不写入标头的 ObjectOuputStream 的子类。

        boolean exists = new File("myFile").exists();
        FileOutputStream fos = new FileOutputStream("myFile", true);
        ObjectOutputStream oos = exists ? 
            new ObjectOutputStream(fos) {
                protected void writeStreamHeader() throws IOException {
                    reset();
                }
            }:new ObjectOutputStream(fos);

然后您可以使用单个对象输入流读回所有记录...

        FileInputStream fis = new FileInputStream("myFile");
        ObjectInputStream ois = new ObjectInputStream(fis);
        while(fis.available() > 0) {
            try {
                Object rper = ois.readObject();
                JOptionPane.showMessageDialog(null, "People:" + rper, "Saved Persons", JOptionPane.INFORMATION_MESSAGE);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        ois.close();

【讨论】:

    【解决方案2】:
    FileOutputStream fos = new FileOutputStream("myFile" , true);
    

    您不能以这种方式append 访问该文件。 grammar of the serialization protocol 简介:

    stream:
      magic version contents
    
    contents:
      content
      contents content
    

    您在文件中乱扔了多个 magic number 和版本字段,当反序列化器遇到这些时,它会引发错误。您必须读取所有提交的值并将它们复制到一个新文件中,并在最后写入新条目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      • 2018-03-12
      • 2015-07-12
      • 2017-09-07
      相关资源
      最近更新 更多