ObjectStreams
- ObjectStreams are a means to write primitive data types
(ints, floats, doubles, etc) or entire objects to a file using one
write statement.
- Data is written in binary (not text) format, taking up less space
on disk. However, since they are binary files, you cannot look at the
file in notepad and make sense of it. Only programs that know the
format of the file can read it.
- If you use an objectstream to read in an object, you are not
required to read the attributes of the object one at a time, instead,
just read
in the object itself.
- Java provides Serialization (converting an
object into a stream of attributes) automatically.
- To write objects to a stream they must be declared as
"serializable", do this with the implements keyword on the
class definition line:
- E.g.
public class Employee implements Serializable
{
- Now objects of type Employee can be written to an objectstream.
- The objectstream will write all nonstatic and non transient
attibutes to the file. Therefore any attribute you define with
the "static" or "transient" keywords will not be
written. You would use the transient keyword on
attributes of data items that either can't be written to the file or
that you don't want to be written to the
file.
- Steps to write objects to an objectstream
- verify that the objects to be written implement "Serializable"
in its class definition line
- create a FileOutputStream
using a file name
FileOutputStream out
= new FileOutputStream(String fileName); or new
FileOutputStream(File file);;
- convert the FileOutputStream to an ObjectOutputStream
ObjectOutputStream objout = new
ObjectOutputStream(out);
- write the objects to the stream using writeObject method
objout.writeObject(object);
- when you are finished, close the stream
objout.close();
- When you write to an objectstream you must catch IOExceptions.
- Note, if you are writing different numbers of objects to
the stream each time you run the program, then it is helpful to first
write the number of objects to the stream as an integer, then write
each object. That way when you read it back in you will know how
many there are. In this example lm refers to a DefaultListModel object.
objout.writeInt(productList.size()); // write out the number of
objects first
for(int i = 0; i <productList.size();
i++) // then write out each object
objout.writeObject(productList.get(i));
- Steps to read in objects from a stream
- create a FileInputStream
based on the file name
FileInputStream in = new
FileInputStream(String fileName); or new FileInputStream(File file);
- convert the FileInputStream into an ObjectInputStream
ObjectInputStream objin = new
ObjectInputStream(in);
- read in the data items in the same order as they were
written using the readObject method. ReadObject returns a
generic object, so you may have to caste the result inorder to save it
in a variable, e.g.
obj = (Employee)
objin.readObject();
- once all objects are read in, then close the stream
objin.close();
- Note: readObject does not return null when you hit the end of
the file, instead, and EOFException is generated. To process
files with a variable number of objects you have two choices,
- first write out the number of objects, then the objects
themselves. when reading back in, read in the number of objects and use
that number
to control a for loop that reads each object in. (preferred)
- second, you could just write out all the objects, then rely on
the EOFException to let you know when you have hit the end of file when
reading them back in.
- When you read from an object stream you must catch IOException
and
ClassNotFoundExceptions. ClassNotFoundExceptions are generated if
you
read an object from the file that your program does not have a class
for.
- example (see code segment above for the write sequence):
Product obj;
int size
= objin.readInt();
for(int i = 0; i < size; i++) // read
in objects one at a time
{
obj = (Product)
objin.readObject();
productList.add(obj);
}
- Basic appliction guidelines for Open, Save, and Save-as
- Open - should ask the user for a file, clear out any existing
data, and read in the new data. The file name should be displayed
in
the title area and remembered in a varaible for future saves.
- Save - should save all data to the last file that was specified
in an open or save-as command. If a file was not previously
opened or created with a save as, then save should ask for the file
- Save as - asks for a new file name, saves all data to the file,
then the file name should be displayed in the title area and remembered
for future saves.
- Other notes:
- It is possible to read and write entire swing objects out
to/from files using ObjectOutputStreams. This makes the job a
little easier, however, the data in those files is
only accessible by reading the entire object back in. Its better
to
store the data in a format that is usable by more than one program.
private void
saveAsItemActionPerformed(java.awt.event.ActionEvent
evt) {//GEN-FIRST:event_saveAsItemActionPerformed
// Add your handling code
here:
// allow the user to specify the file to write to
//
JFileChooser chooser = new JFileChooser();
int result =
chooser.showSaveDialog(this);
if(result != JFileChooser.APPROVE_OPTION)
return;
File file = chooser.getSelectedFile();
fileName = file.getPath();
setTitle("ObjectStream Demo : "+fileName); //
set
the title
//
// create an output stream connection to the file
try{
FileOutputStream out = new
FileOutputStream(fileName);
ObjectOutputStream objout = new
ObjectOutputStream(out);
//
// write out the number of objects in the vector,
followed
by the objects themselves
//
objout.writeInt(productList.size());
// write out the number of objects first
for(int i = 0; i <
productList.size();
i++) // then write out each object
objout.writeObject(productList.get(i));
objout.close();
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
private void
openItemActionPerformed(java.awt.event.ActionEvent
evt) {//GEN-FIRST:event_openItemActionPerformed
// Add your handling code
here:
try{
//
// allow the user to select the file
JFileChooser chooser = new
JFileChooser();
int result =
chooser.showOpenDialog(this);
if(result != JFileChooser.APPROVE_OPTION)
return;
File file = chooser.getSelectedFile();
fileName = file.getPath();
//
// display the file name in the title
setTitle("ObjectStream Demo :
"+fileName);
// set the title
//
// create an object stream connection to the file
//
FileInputStream in = new
FileInputStream(fileName);
ObjectInputStream objin = new
ObjectInputStream(in);
//
// Empty out the vector to receive the items
//
productList.removeAllElements(); //
empty
the list
currentItem = -1;
// read in the number of objects first
int size;
size = objin.readInt();
// then read in each object
for(int i = 0; i < size; i++)
//
read in objects one at a time
{
Object obj =
objin.readObject();
productList.add(obj);
}
objin.close();
currentItem = size-1;
displayProduct();
}
catch (IOException e)
{
System.out.println("IOException :
"+e.getMessage());
}
catch(ClassNotFoundException e)
{
System.out.println("ClassNotFoundException
: "+e.getMessage());
}
}//GEN-LAST:event_openItemActionPerformed