3

I am trying to create a simple program with user interface. The user from gui inserts a name, surname and age, of a class Person Implements Serializable.

Everything works just fine, but only for one person, the first person! It seems that every time I send a new object to my file it is indeed written to the file since the file size is getting larger.

The problem is that when I read the file with objects it returns just one, I want all the objects of class person that are stored in myFile to be returned.

Here is a sneak peek of my code:

Write object Button:

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
}

Read object button:

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
}

Thanks for any info!

5
  • Please learn to format your code. This question will be ignored by most people because it is impossible to read. How do you even understand what your code it doing? Commented Mar 1, 2014 at 10:48
  • @BoristheSpider I think it is ultra basic, do I even need to comment the above code? Commented Mar 1, 2014 at 10:53
  • I see no loop at all in your code, although your question is about writing and reading multiple persons. Commented Mar 1, 2014 at 10:56
  • @JBNizet Uhm yes, but how I know where every object ends? Commented Mar 1, 2014 at 10:58
  • You write several objects at once in the ObjectOutputStream, and you read objects from the ObjectInputStream until you get an exception signalling the end of the stream. Or easier, you write a single List<Person> to the stream, and read a single List<Person> from the stream. Commented Mar 1, 2014 at 11:02

2 Answers 2

5

Every time you open the file, a header is written to it. When the input stream reader sees this header after its first read, it throws an exception. Since you don't have any "printStackTrace" calls in your exception handling, you are not seeing that error.

The fix is to prevent the header from getting written on subsequent calls when you open the stream. Do this by checking for the existence of the file before opening it, and if it already exists, use a subclass of ObjectOuputStream that doesn't write the header.

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

Then you can read all the records back in using a single object input stream...

        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();
Sign up to request clarification or add additional context in comments.

Comments

2
FileOutputStream fos = new FileOutputStream("myFile" , true);

You cannot append to the file this way. The grammar of the serialization protocol in brief:

stream:
  magic version contents

contents:
  content
  contents content

You are littering the file with multiple magic number and version fields and when the deserializer encounters these it throws an error. You must read all the committed values and copy them to a new file, writing the new entry at the end.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.