4

Im developing a large scale GUI program, where I have alot of project data that needs to be stored locally on command.

Currently, I'm saving all the global data structures in a save class (project), and then serializing them to a local harddisk file:

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());

}

Now i'm serializing this to a local file:

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();
    }
}

My question is this: Is there a default; or better way to save files on your local harddrive? I dont want to use XML or any DB.

  • Thanks in advance
Daniel Mac
  • 400
  • 2
  • 14
  • To forestall suggestions that will not match your needs, it may be useful to say more about why you don't want to use XML or a database. Is that a personal preference, in which case a good argument could convince you otherwise? Or a hard requirement of the project for some reason? – jfrank Aug 27 '13 at 18:13

3 Answers3

2

For swing applications, I really like using XML. This has the added benefit of making your saved data potentially useful for other applications. JAXP provides ways to write and read XML data within your program - all you would need to do is write some code in order to persist and recreate the state that you are saving.

If you are writing a lot of data (it sounds like you are), I would recommend using the SAX interface for reading it into your application. There is a tutorial on doing that here.

Another way to go about storing the data is by using a database. Using something like Apache Derby would be an option as well.

Surveon
  • 729
  • 5
  • 12
  • XML is out of the question, sry should've added that to the question – Daniel Mac Aug 27 '13 at 17:00
  • 1
    A heads up for a question like this though - people have their preferences for how they store state. If what you are doing is working for you and the performance is acceptable, it is a correct way to do it. There are some advantages to doing it in other ways, but they may not be relevant in your case. – Surveon Aug 27 '13 at 17:00
  • As an addtional comment to your latest edit. I'm developing this as an exact contrary to using a DB like mySQL etc. It has to be stored locally. – Daniel Mac Aug 27 '13 at 17:06
  • One of the nice things about Derby is that it allows you to use it in a local manner. The [tutorial](http://db.apache.org/derby/papers/DerbyTut/embedded_intro.html) here introduces the embedded mode. This basically allows you to use Derby in a manner that seems consistent with your requirement. – Surveon Aug 27 '13 at 17:08
  • @ Surveon thats not what Im looking for – Daniel Mac Aug 27 '13 at 17:10
  • Understood. Consider looking through the question [here](http://stackoverflow.com/questions/450864/lightweight-java-persistence) and checking if any of those solutions seem like they might work for you. – Surveon Aug 27 '13 at 17:13
  • I did that. They did not. – Daniel Mac Aug 27 '13 at 17:32
2

In my opinion, serialization is something that is very hard to use in the right place.
Sometimes it gets used as a placeholder, because of its low maintenance requirements and ease to setup. However my points against using (automatic) Serialization as a silver bullet (Don't get me wrong, serialization is fun and there are many cases where its use is appropriate) are these:

  • Speed: Standard Java serialization is slow. Not necessarily, but if used without preparation. Workaround: Own writeObject/readObject methods.

  • Versioning: Sure, it pays attention to not deserialize stuff that's too old (serialVersionUID), but it cannot upgrade your internal structure. If you change the way you do things internally, your old saves are useless.

  • Binary Format: You're stuck to standard Java Serialization... You can't (without workarounds) change to another format, neither can you read it from another language...

One Alternative:

It looks like you don't want a database or xml (I'm just going to assume JSON is a no-go either). So, what's left is designing your own format and writing data in binary format. This gives you maximum flexibility (I don't say its easier than text-formats though) and, if applied correctly, much better speed than Java Serialization or xml.

The advantages however come at a cost: There is not prebuilt system (how should there be?) which simply does it. You'll have to write some more code than with Java Serialization and believe me, (big) structured binary files can be annoying to debug...

An Example:

Imagine you have an object called Data. It contains an array of floats. On writeObject, you write the size of that array, and then write each float in the stream.
On readObject, you read the size of the array, create an array of that size and fill each element in the array with the read floats.

Community
  • 1
  • 1
tilpner
  • 4,351
  • 2
  • 22
  • 45
2

I'm having trouble making an actual recommendation because I don't understand well enough why you wouldn't consider XML or an embedded database. But here are some things to think about.

  • Versioning. What if you need to add a field to one of your objects, but you already have some saved files without that field? Depending on which technique you use for saving state, this can be a huge pain or a moderate pain. I don't think java object serialization handles this easily.

  • Object identity. In the code snippet above, the project is identified by its name, which may also serve as a human-friendly identifier. In general it's better to have a "meaningless" property to use for identity. This way you can change the name of a project and still have it be the "same" object. You also have to worry about collisions, with 2 different objects getting the same identity, particularly if it's a user-specified property.

Now here are a few other storage formats that you might consider, again without knowing your constraints.

  • JSON. The Jackson serialization library is great for saving / loading java objects in JSON format. If you have "java bean" style objects, it's very easy to use. One nice feature is that you can configure it so that a new object property won't cause a problem when reading in an old object.

  • Binary, e.g. Protocol Buffers. These are faster than JSON, but not as easy to use. It can handle additional fields without a problem.

jfrank
  • 723
  • 3
  • 9