Java I/O How to - Save custom object to a binary file with RandomAccessFile








Question

We would like to know how to save custom object to a binary file with RandomAccessFile.

Answer

// w  ww .  j a va 2s .co  m
import java.io.DataInput;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;

public class Main {
  public static void main(String[] args) {
    Employee[] staff = new Employee[3];

    staff[0] = new Employee("Harry Hacker", 35000);
    staff[1] = new Employee("Carl Cracker", 75000);
    staff[2] = new Employee("Tony Tester", 38000);
    try {
      DataOutputStream out = new DataOutputStream(new FileOutputStream(
          "employee.dat"));
      for (int i = 0; i < staff.length; i++)
        staff[i].writeData(out);
      out.close();
    } catch (IOException e) {
      System.out.print("Error: " + e);
      System.exit(1);
    }

    try {
      RandomAccessFile in = new RandomAccessFile("employee.dat", "r");
      int count = (int) (in.length() / Employee.RECORD_SIZE);
      Employee[] newStaff = new Employee[count];

      for (int i = count - 1; i >= 0; i--) {
        newStaff[i] = new Employee();
        in.seek(i * Employee.RECORD_SIZE);
        newStaff[i].readData(in);
      }
      for (int i = 0; i < newStaff.length; i++)
        newStaff[i].print();
    } catch (IOException e) {
      System.out.print("Error: " + e);
      System.exit(1);
    }
  }
}

class Employee {
  public static final int NAME_SIZE = 40;

  public static final int RECORD_SIZE = 2 * NAME_SIZE + 8 + 4 + 4 + 4;

  private String name;

  private double salary;

  public Employee(String n, double s) {
    name = n;
    salary = s;
  }

  public Employee() {
  }

  public void print() {
    System.out.println(name + " " + salary);
  }
  public void writeData(DataOutput out) throws IOException {
    DataIO.writeFixedString(name, NAME_SIZE, out);
    out.writeDouble(salary);
  }

  public void readData(DataInput in) throws IOException {
    name = DataIO.readFixedString(NAME_SIZE, in);
    salary = in.readDouble();
  }
}

class DataIO {
  public static String readFixedString(int size, DataInput dataInput)
      throws IOException {
    StringBuffer strBuffer = new StringBuffer(size);
    int count = 0;
    boolean more = true;
    while (more && count < size) {
      char aChar = dataInput.readChar();
      count++;
      if (aChar == 0)
        more = false;
      else
        strBuffer.append(aChar);
    }
    dataInput.skipBytes(2 * (size - count));
    return strBuffer.toString();
  }

  public static void writeFixedString(String str, int size, DataOutput dataOutput)
      throws IOException {

    for (int i = 0; i < size; i++) {
      char aChar = 0;
      if (i < str.length())
        aChar = str.charAt(i);
      dataOutput.writeChar(aChar);
    }
  }
}

The code above generates the following result.