【问题标题】:ObjectOutputStream writing array to file with inherited classes not writing to fileObjectOutputStream 将数组写入文件,继承的类不写入文件
【发布时间】:2015-01-27 12:58:54
【问题描述】:

我的任务是将员工列表保存为二进制文件(然后从中读取)。我现在正在处理输出部分,下面是有问题的函数块。这个函数确实还有大约 10 行,但它们在 TextField 数组列表上编辑内容。

Employee类是Supervisor类和Secretary类的父类。 all 是包含所有员工、秘书和员工对象的 ArrayList。

我使用的是 netbeans 8.0.2,当程序运行并单击 gui 中的保存按钮(onActionEvent() 是此函数)时,没有编译器错误。 “IO 错误”或“无权限...”不输出。我尝试在已经创建和不创建 employees.dat 文件的情况下保存。

我现在不确定该怎么做,我考虑将每个对象保存为 int、String 等的集合,但这很愚蠢,它应该能够以这种方式工作......对吗?

编辑: 员工、主管和秘书都是可序列化的。

private void saveChanges(ArrayList<Employee> all, ArrayList<TextField> text, int index) {


    try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {

        for (int i = 0; i < all.size(); i++) {
            if (all.get(i).getClass() == (new Secretary().getClass()))
                output.writeObject(new Secretary((Secretary) all.get(i)));
            else if (all.get(i).getClass() == (new Supervisor().getClass()))
                output.writeObject(new Supervisor((Supervisor) all.get(i)));
            else
                output.writeObject(new Employee(all.get(i)));
        }

        output.flush();
    } catch (IOException io) {
        io.printStackTrace();
    } catch (SecurityException se) {
        se.printStackTrace();
    }
}

编辑:

我已将 try-catch 编辑到此代码...

try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {

                output.writeObject(all);


        output.flush();
        output.close();
    } catch (IOException io) {
        io.printStackTrace();
    } catch (SecurityException se) {
        se.printStackTrace();
    }

仍然没有写入文件。我在 .java 文件所在的文件夹中拥有权限。

【问题讨论】:

  • 为什么要进行所有类测试和“复制构造”?只写对象。其实只要写list.一行代码。你不需要这一切。注意,您不能附加到作为对象输出流创建的文件,至少不是那样。您只需在某处找到异常和堆栈跟踪,然后发布它们。
  • 为什么不使用“instanceof”而不是使用 == 检查类类型,并确保对象被强制转换为正确的类类型,并在编写对象之前尝试显式类型转换尝试调试和检查一次值以确保对象转换为正确的目标类型。
  • @Vigneshearan.m 为什么要这样做?这是毫无意义。只需编写对象或列表即可。
  • 我认为您正在读取多种对象类型并在编写时进行转换,即“(new Employee(all.get(i)))”而不是尝试output.writeObject(all.get(i) );这就是我的猜测
  • @Vigneshearan.m 这不是演员表,而是构造函数。

标签: java inheritance arraylist output objectoutputstream


【解决方案1】:
    try ( ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("employees.dat", true)); ) {

将true 更改为false,或将其删除。您不能追加到作为对象输出流创建的文件,至少不能像这样,而且您是否应该这样做还有待商榷。

        for (int i = 0; i < all.size(); i++) {
            if (all.get(i).getClass() == (new Secretary().getClass()))
                output.writeObject(new Secretary((Secretary) all.get(i)));
            else if (all.get(i).getClass() == (new Supervisor().getClass()))
                output.writeObject(new Supervisor((Supervisor) all.get(i)));
            else
                output.writeObject(new Employee(all.get(i)));
        }

把这整个烂摊子改成这样:

output.writeObject(all);

如果这仍然不起作用,那么一定是某个地方出现了异常,您只需要找到它,打印它,然后发布它。将其编辑到您的问题中。否则你正在查看错误的文件。

注意,您还必须更改读取文件的代码,以便在单个 readObject() 调用中读取列表。

【讨论】:

    【解决方案2】:

    您是否碰巧在没有适当权限的情况下编写了小程序或 JNLP?

    您对输出文件的文件夹有写入权限吗? (在这种情况下是程序运行所在的目录。)

    我建议调用 io.printStackTrace() 和 se.printStackTrace();在异常处理程序中提供有关异常的更多信息。

    在文件写入结束时也不要忘记调用 output.close() 以确保正确关闭流,写入数据尾部并且系统上没有剩余的打开文件句柄。

    【讨论】:

    • 我按照您的建议更改了 catch 并重新测试。没有错误,但文件仍然是 0 字节(它应该写入 2 个对象,一个 Employee 和 Supervisor)。我正在写 JavaFX。
    • 您似乎也忘记在流上调用“关闭”
    • @DamianNikodem 不,他正在使用 try-with-resources;关闭是自动的。
    • @EJP 在这种情况下,可能建议将其重写为普通的 try/catch 块,因为在关闭期间可能会出现异常。
    • @DamianNikodem A flush() 在 try 块内会是一个更好的解决方案。这是唯一可以让close() 投入实践的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多