2

I am trying to understand object serialization better, so I am practicing with some code I got from my textbook. (My textbook doesn't explain how to read and write/append objects to a serialization file every time the program starts, which is what I need to do.) I took their program, which just overwrites existing data in a file with the objects from the current session, and add code to it so that it will append the objects and read the whole file instead. I found something really useful here: Appending to an ObjectOutputStream but even if I create a subclass of ObjectOutputStream, override the writeStreamHeader method, and call this subclass if the file already exists, which is what they did, it still throws a CorruptedStreamException. My guess is that I would need to set the pointer back to the beginning of the file, but that doesn't seem to be necessary as there is only one ObjectOutputStream. So, my question is, what else could I possibly need to do?

EDIT: Here is some code.

WriteData.java

import java.io.*;
import java.util.Scanner;

public class WriteData 
{
    private int number;
    private String name; 
    private float money;
    private ObjectInputStream testopen;
    private ObjectOutputStream output;  //This is for the output. Make sure that
    //this object gets an instance of FileOutputStream so that it can write objects
    //to a FILE.
    private AppendObjectOutputStream appendobjects;
    static Scanner input = new Scanner(System.in);
    static DataClass d;

    public void openfile()
    {
        //Try opening a file (it must have the ".ser" extension).
        try
        {
            //output = new ObjectOutputStream(new FileOutputStream("test.ser"));
            testopen = new ObjectInputStream(new FileInputStream("test.ser"));
        }
        //If there is a failure, throw the necessary error.
        catch (IOException exception)
        {
            try 
            {
                output = new ObjectOutputStream(new FileOutputStream("test.ser"));
            } 
            catch (FileNotFoundException e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }   //end case createfile
        if (testopen != null)
        {
            try 
            {
                testopen.close();
                appendobjects = new AppendObjectOutputStream(
                        new FileOutputStream("test.ser"));
            } 
            catch (FileNotFoundException e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            catch (IOException e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public void writedata()
    {
        //write the data until the user enters a sentry value.
        System.out.println("Enter CTRL + z to stop input.\n");
        System.out.print ("Enter the data in the following format: " +
                "account_number name balance\n->");
        while (input.hasNext())
        {
            System.out.print ("Enter the data in the following format: " +
                        "account_number name balance\n->");
            try
            {
                number = input.nextInt();
                name = input.next();
                money = input.nextFloat();

                //Make object with that data
                d = new DataClass(number, name, money);
                //write it to the file
                if (output != null)
                {
                    output.writeObject(d);
                }
                else if (appendobjects != null)
                {
                    appendobjects.writeObject(d);
                }
            }
            catch (IOException e)
            {
                System.out.println("Error writing to file.");
                return;
            }
        }
        System.out.println("\n");
    }   //end writedata
    public void closefile()
    {
        try 
        {
            if (output != null)
            {
                output.close();
            }
            else if (appendobjects != null)
            {
                appendobjects.close();
            }
        }
        catch (IOException e)
        {
            System.out.println("Error closing file. Take precautions");
            System.exit(1);
        }
    }
}

DataClass.java

import java.io.Serializable;

public class DataClass implements Serializable
{
    private int someint;
    private String somestring;
    private float somefloat;
    public DataClass(int number, String name, float amount) 
    {
        setint(number);
        setstring(name);
        setfloat(amount);
    }
    public void setint(int i)
    {
        this.someint = i;
    }
    public int getint()
    {
        return someint;
    }
    public void setstring(String s)
    {
        this.somestring = s;
    }
    public String getstring()
    {
        return somestring;
    }
    public void setfloat(float d)
    {
        this.somefloat = d;
    }
    public float getfloat()
    {
        return somefloat;
    }
}

AppendObjectOutputStream.java

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;


public class AppendObjectOutputStream extends ObjectOutputStream 
{
    public AppendObjectOutputStream(FileOutputStream arg0) throws IOException 
    {
        super(arg0);
        // TODO Auto-generated constructor stub
    }
    //This is a function that is default in ObjectOutputStream. It just writes the 
    //header to the file, by default. Here, we are just going to reset the 
    //ObjectOutputStream
    @Override
    public void writeStreamHeader() throws IOException
    {
        reset();
    }

}

ReadData.java

import java.io.*;
import java.util.Scanner;

public class ReadData 
{ 
    private FileInputStream f;
    private ObjectInputStream input;    //We should the constructor for this 
    //object an object of FileInputStream
    private Scanner lines;
    public void openfile()
    {
        try
        {
            f = new FileInputStream("test.ser");
            input = new ObjectInputStream (f);
            //input.reset();
        }
        catch (IOException e)
        {
            e.printStackTrace();
            System.exit(1);
        }
    }
    public void readdata()
    {
        DataClass d;
        System.out.printf("%-15s%-12s%10s\n", "Account Number", "First Name",
                "Balance");
        try
        {
            while (true)
            {
                d = (DataClass)input.readObject();  //define d
                //read data in from d
                System.out.printf("%-15d%-12s%10.2f\n", d.getint(), d.getstring(),
                        d.getfloat());
            }
        }
        catch (EOFException eof)
        {
            return;
        } 
        catch (ClassNotFoundException e) 
        {
            System.err.println("Unable to create object");
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        }

    }
    public void closefile()
    {
        try
        {
            if (input != null)
            {
                input.close();
            }
        }
        catch (IOException ex)
        {
            System.err.println("Error closing file.");
            System.exit(1);
        }
    }
}

SerializationTest.java

public class SerializationTest 
{

    public static void main(String[] args)
    {
        ReadData r = new ReadData();
        WriteData w = new WriteData();
        w.openfile();
        w.writedata();
        w.closefile();
        r.openfile();
        r.readdata();
        r.closefile();

    }
}
Community
  • 1
  • 1
Mike Warren
  • 3,796
  • 5
  • 47
  • 99

3 Answers3

1

I suggest to do it this way

    ObjectOutputStream o1 = new ObjectOutputStream(new FileOutputStream("1"));
    ... write objects
    o1.close();
    ObjectOutputStream o2 = new AppendingObjectOutputStream(new FileOutputStream("1", true));
    ... append objects
    o2.close();

it definitely works.

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
1
import EJP;
import Evgeniy_Dorofeev;

public class answer
{
    private String answera, answerb;
    public answer(String a, String b)
    {
        answera = a;
        answerb = b;
    }
    public void main(String[] args)
    {
        answer(EJP.response(), Evgeniy_Dorofeev.response());
        System.out.println(answera + '\n' + answerb);
    }
}
Mike Warren
  • 3,796
  • 5
  • 47
  • 99
0

You need to add a 'true' for the append parameter of new FileOutputStream() in the case where you are appending. Otherwise you aren't. Appending, that is.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Thanks guys! Now, I am practically ready to release stage two of the beta test for my game. You both just helped me with this.... – Mike Warren Jan 31 '13 at 06:22
  • @MikeWarren If any of the answers are useful you should upvote them, and accept the one you consider most correct, as a guide for future readers. – user207421 Jan 31 '13 at 07:44