-1

I was trying out a program that was given in the exercise at the end of the chapter 'Serialization'.

The program requires me to declare a class Person which encapsulates only two data members of type Name and Address , which are also classes. Then I have to take a series of names and addresses from the keyboard , create objects and write them to the file. However , if the FILE ALREADY EXISTS then the objects must be APPENDED to the existing file. My program runs perfectly for the first time but for the second time , when I try to read back the appended records , I get an Exception

java.io.StreamCorruptedException: invalid type code: AC 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1374) 
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369) 
at Trial.main(Trial.java:66) 

I did my bit of research on this and found that the StreamHeader can be written ONLY ONCE and appending corrupts it. What is the way around it ???
The Object Writing Code is:

try(ObjectOutputStream stream = new ObjectOutputStream(new BufferedOutputStream(Files.newOutputStream(filePath,WRITE,CREATE,APPEND)))) {
        for(int i = 0;i<name.length;i++) {
            Person aPerson = new Person(name[i],address[i]);
            System.out.println(aPerson);
            stream.writeObject(aPerson);
            stream.reset();
            aPerson = null;
        }
        System.out.println("Writing Complete");
Mat
  • 202,337
  • 40
  • 393
  • 406
A User
  • 375
  • 2
  • 4
  • 13
  • Extension `.txt` suggest the file contains human readable text. Object stream is binary. – Piotr Praszmo May 29 '12 at 12:15
  • Serialization does not produce text. You are not appending objects to a text file, and you should not be using the `.txt` filename extension. – user207421 Aug 25 '17 at 00:35

2 Answers2

0

Yes, I've had this problem myself before... it is not possible, unfortunately.

What you could do is to place your objects into a List and persist the full list at a time. As the list is an object it can persisted just as easily. I know this is terrible as this require the entire contents to be read into memory, but it is the only way as far as I know.

The other option (which I recommend) is that you use something like JSon to commit your data. GSon works quite well for this purpose. You can then simply marshall and unmarshall your objects which can be committed to a text file. It's very easy to do as a single line of code is required to go either way (object to JSon-string and vice versa).

Jaco Van Niekerk
  • 4,180
  • 2
  • 21
  • 48
  • @Mat Im a beginner :) What I was thinking (a rather combursome way) was to read the objects back , and write them back along with new objects. However this is not very efficient :) And do you mean LINKED LIST ? – A User May 29 '12 at 12:12
  • Yes, I do. I LinkedList or an ArrayList will do the trick. (We're all beginners :-)) I agree with you that it is cumbersome, but ObjectOutputStream does not add multiple records. – Jaco Van Niekerk May 29 '12 at 12:24
  • I have no knowledge of ArrayList :) – A User May 29 '12 at 12:42
  • **@bozho** I have to run the code twice so as to add more names and addresses that the user provides :) Apart from that , for writing once , my program works just fine **@banthar** I know that but im simply saving it in txt to be able to open and see how it is written :) You can actually see the textual data that is written :) – A User May 29 '12 at 12:47
0

This works. So debug your program and see why it doesn't. Probably don't call reset()

public class ClassTest {

    public static void main(String a[]) throws Exception {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("c:/temp/foo.txt"));
        oos.writeObject(new Test("foo", "bar"));
        oos.writeObject(new Test("baz", "brr"));
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("c:/temp/foo.txt"));
        System.out.println(ois.readObject());
        System.out.println(ois.readObject());
        ois.close();
    }
}

class Test implements Serializable {
    private String fld1;
    private String fld2;
    public Test(String v1, String v2) {
        this.fld1 = v1;
        this.fld2 = v2;
    }

    @Override
    public String toString() {
        return "Test [fld1=" + fld1 + ", fld2=" + fld2 + "]";
    }
}
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • Bozho you are writing Test object twice without closing the output stream. if you close the stream and than reopen, than this problem occur. i have also such problem. java.io.StreamCorruptedException: invalid type code: AC any one help –  May 29 '13 at 16:58
  • @user2433486 That is the *point*. He is telling you *not* to close the stream between object writes. – user207421 Aug 25 '17 at 00:36