保存项目数据。你会怎么做?

时间:2013-08-27 16:49:22

标签: java swing user-interface arraylist save

我正在开发一个大规模的GUI程序,我有很多需要在命令中存储locally的项目数据。

目前,我将所有全局数据结构保存在保存类(项目)中,然后将它们序列化为本地硬盘文件:

public void saveChanges() {
    ArrayList<Student> studentList = new ArrayList<>();
    ArrayList<String> coursesList = new ArrayList<>();
    ArrayList<Requirement> reqList = new ArrayList<>();
    ArrayList<Risk> riskList = new ArrayList<>();
    for (int x = 0; x < dlm.getSize(); x++) {
        studentList.add(dlm.elementAt(x));
    }
    for (int x = 0; x < dlm2.getSize(); x++) {
        coursesList.add(dlm2.elementAt(x));
    }
    for (int x = 0; x < dlm3.getSize(); x++) {
        reqList.add(dlm3.elementAt(x));
    }
    for (int x = 0; x < riskTable.getRowCount(); x++) {
        riskList.add((Risk) riskMap.get(dtm1.getValueAt(x, 0)));
    }

    project.setStudentAL(studentList);
    project.setCoursesAL(coursesList);
    project.setReqAL(reqList);
    project.setRiskAL(riskList);
    project.setLastUpdated(new Date().toString());

}

现在我将其序列化为本地文件:

public void saveProject(boolean defaultPath, String path) {
    saveChanges();
    FileOutputStream outFile;
    try {
        if (defaultPath) {
            outFile = new FileOutputStream(directory + project.getProjectName() +    ".proj");
        } else {
            outFile = new FileOutputStream(path + ".proj");
        }
        ObjectOutputStream outObject = new ObjectOutputStream(outFile);
        outObject.writeObject(project);
        outObject.close();
    } catch (IOException e) {
        System.out.println("Failed to save project");
        e.printStackTrace();
    }
}

我的问题是: 有默认值;或者更好的方法来保存本地硬盘上的文件?我不想使用XML或任何数据库。

  • 提前致谢

3 个答案:

答案 0 :(得分:2)

对于swing应用程序,我真的很喜欢使用XML。这样做的另一个好处是可以使您保存的数据对其他应用程序有用。 JAXP提供了在程序中编写和读取XML数据的方法 - 您需要做的就是编写一些代码,以便持久化并重新创建您正在保存的状态。

如果您正在编写大量数据(听起来像是这样),我建议使用SAX界面将其读入您的应用程序。有一个关于这样做的教程here

存储数据的另一种方法是使用数据库。使用像Apache Derby这样的东西也是一种选择。

答案 1 :(得分:2)

在我看来,serialization是在正确的地方很难使用的东西 有时它会被用作占位符,因为它的维护要求低且易于设置。但是我的指向使用(自动)序列化作为银弹(不要误解,序列化很有趣,并且在很多情况下它的使用是合适的)是这些:

  • 速度:标准Java序列化很慢。不一定,但如果没有准备就使用。 解决方法:拥有writeObject/readObject方法。

  • 版本控制:当然,它注意不要反序列化太旧的东西(serialVersionUID),但它不能升级你的内部结构。如果你改变你在内部做事的方式,你的旧保存是无用的。

  • 二进制格式:您坚持使用标准Java序列化...您不能(没有解决方法)更改为其他格式,也不能从其他语言中读取它...

一种选择

看起来你不想要数据库或xml(我只是假设JSON也是禁止的)。那么,剩下的就是设计自己的格式并以二进制格式编写数据。这给了你最大的灵活性(虽然我并不比文本格式更简单),如果应用得当,比Java Serialization或xml要快得多。

然而,优势是有代价的:没有预先构建的系统(应该怎么做?)只是 它。你需要编写比Java Serialization更多的代码,并且相信我,(大)结构化二进制文件可能会令人讨厌...

示例

想象一下,你有一个名为Data的对象。它包含一系列浮动。 在writeObject上,编写该数组的大小,然后在流中写入每个float 在readObject上,您读取数组的大小,创建一个该大小的数组,并使用read浮点填充数组中的每个元素。

答案 2 :(得分:2)

我无法提出实际建议,因为我不太了解您为什么不考虑XML或嵌入式数据库。但是这里有一些事情要考虑。

  • 版本。如果您需要向其中一个对象添加字段,但是您已经有一些没有该字段的已保存文件,该怎么办?根据您用于保存状态的技术,这可能是巨大的疼痛或中度疼痛。我不认为java对象序列化可以轻松处理这个问题。

  • 对象标识。在上面的代码片段中,项目由其名称标识,该名称也可以用作人性化的标识符。一般来说,拥有一个没有意义的&#34;会更好。用于身份的财产。通过这种方式,您可以更改项目的名称,并且仍然可以使用&#34;相同的&#34;宾语。您还必须担心碰撞,2个不同的对象获得相同的身份,特别是如果它是用户指定的属性。

现在,您可以考虑使用其他一些存储格式,同样不知道您的约束。

  • JSON。 Jackson序列化库非常适合以JSON格式保存/加载Java对象。如果你有&#34; java bean&#34;样式对象,它非常容易使用。一个很好的功能是你可以配置它,以便在读取旧对象时新的对象属性不会导致问题。

  • 二进制,例如协议缓冲区。这些比JSON快,但不是那么容易使用。它可以毫无问题地处理其他字段。