[JAVA] Appending Objects to File

fasihxkhatib

Distinguished
Aug 25, 2011
74
0
18,580
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 ???


In the source code , UserInput is a class encapsulating StreamTokenizer object. The parameter is passed to the quoteChars() method to enable easy tokenization of user input

Source code:
import static java.nio.file.StandardOpenOption.*;
import java.util.EnumSet;
import java.nio.file.*;
import java.io.*;
public class Trial {
public static void main(String[] args) {
char n = '0';
String nString = null;
int nEntering = 0;
UserInput keyboard = new UserInput('\"');
Path filePath = Paths.get("C:/Documents and Settings/USER/Beginning Java 7/nameNaddress.txt");
try {
System.out.println("How many records do you want to enter? ");
n = (char) System.in.read();
nString = Character.toString(n);
nEntering = Integer.parseInt(nString);
if(nEntering == 0) {
System.exit(1);
}
}catch(IOException e) {
e.printStackTrace();
}
String[] name = new String[nEntering];
String[] address = new String[nEntering];
for(int i = 0; i<nEntering;i++) {
System.out.println("Enter A Name: ");
name = keyboard.read();
System.out.println("Enter Address: ");
address = keyboard.read();
}
System.out.println("Beginning Writing...");
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,address);
System.out.println(aPerson);
stream.writeObject(aPerson);
stream.reset();
aPerson = null;
}
System.out.println("Writing Complete");
}catch(IOException e) {
e.printStackTrace();
}

System.out.println("Displaying all records...");
try(ObjectInputStream iStream= new ObjectInputStream(new BufferedInputStream(Files.newInputStream(filePath)))) {
while(true) {
Person aPerson = (Person)iStream.readObject();
System.out.println(aPerson);
aPerson = null;
}
}catch(EOFException e) {
System.out.println("EOF Reached");
}catch(IOException |ClassNotFoundException e) {
e.printStackTrace();
}
}
}
 

randomizer

Distinguished
I'm not overly familiar with Java, but I'd like to point out a side issue:

Code:
try (...)
{
    while(true) {
        Person aPerson = (Person)iStream.readObject();
        System.out.println(aPerson);
        aPerson = null;
    }
} catch(EOFException e) {
        System.out.println("EOF Reached" );
} catch(IOException |ClassNotFoundException e) {
    e.printStackTrace();
}

It looks like this code is always going to throw an EOFException and that this is the expected behaviour. Exceptions are for exceptional cases, not for normal behaviour. Don't use an exception to determine if you've reached the end of the file. Also, any time that you're using an infinite while loop (and not just for reprinting a menu in a command line application), you should re-think your logic. There's a good chance that you're writing a hack :)