Google
 
Site navigation: [ Home | Theory | Java | Moodle courses | Resource wiki | About ]

Random Access Files

File handling application

It's not pretty

 

 

 

 

 

Main calls the constructor

Which does all the work

 

 

 

 

If you can be bothered to convert this to a char data type then you could use a switch here.

 

 

 

 

 

 

 

 

 

 

 

 

On to the main methods called by the menu loop

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Given the record number, seek to that position in the file.

Then read the data.

readString is a helper method (later)

 

 

 

 

 

 

 

 

 

 

 

The application that manipulates the RAF records.

import java.io.*;
/**
* Maintains a RAF of Member data. It ain't purty y'all.
*
* @author Down Home Redneck Ricky
* @version 20071007
*/

public class MemberDatabase
{
  private static String FILENAME = "members.raf";
  RandomAccessFile theFile;

  // Make it a runnable class
  public static void main(String[] args) { new MemberDatabase(); }

  // Constructor for objects of class MemberDatabase
  public MemberDatabase()
  {
    // OK let's set up and initialise an RAF
    try
    {
      theFile = new RandomAccessFile(FILENAME, "rw");

      // main menu loop - very primitive
      String c = "q";
      do
      {
         output("add, remove, list, quit (a, r, l, q)");
         c = input(">");
         if (c.equals("a"))
         {
           addMember();
         }
         else if (c.equals("r"))
         {
           deleteMember();
         }
         else if (c.equals("l"))
         {
           listMembers();
         }
         else if (c.equals("q"))
         {
           theFile.close();
           System.exit(0);
         }
         else
         {
           output("Command unknown");
         }
       }while (c != "q");
     }
     catch(IOException io)
     {
        output("Some error opening the client data file");
        System.exit(1);
     }
  }
  /**
  * Collects Member data to be inserted in the file
  * this method could be replaced by one that gets the Member data
  * some other way, eg via a GUI or direct from the user.
  */

  public void addMember()
  {
    // get the member data from the Console Class
    MemberConsole mc = new MemberConsole();
    Member m = mc.getMemberConsole();
    if (m != null)
    {
      insert(m);
    }
    else
    {
      output("Some error obtaining record");
    }
  }
  /**
  * Gets a Member ID, searches the file and if it exists, calls delete
  * to remove the record
  */

  public void deleteMember()
  {
    int n = inputInt("Member id to delete: ");
    long f = searchMember(n);
    if (f != -1)
    {
      delete(f);
    }
    else
    {
      output("Member not found");
    }
  }
  /**
  * list all the records in the file
  */

  public void listMembers()
  {
    for(long x = 0; x <= numRecords(); x++)
    {
      Member m = readMember(x);
      output(m.toString());
    }
  }
  /**
  * This method reads a record from the file
  * @param the record number of the record in the file
  * @return a reference to a Member instance (or null)
  */
  public Member readMember(long recordNumber)
  {
    try
    {
      long filePos = recordNumber * Member.RECORD_LENGTH;
      if (filePos < theFile.length())
      {
        theFile.seek(filePos);
        int cb = theFile.readInt();
        String fb = readString(Member.FIRST_L);
        String lb = readString(Member.LAST_L);
        boolean pb = theFile.readBoolean();
        // This line could help trace what is actually read from the file,
        // in case it is not what you expected.
        //System.out.println("read: " + cb + "@" + fb + "@" + lb + "@" + pb);
        return new Member(cb, fb, lb, pb);
       }
       else // file pos exceeds file length
       {
        output("ReadMember: File pos exceeds file length");
        return null;
       }
     }
     catch(IOException ioe)
     {
        System.out.println("ReadMember: " + ioe.getMessage());
        return(null);
     }
  }
  /**
  * This method writes a record to the file
  * @param the record to be written
  * @param the record number of the record in the file
  * @return error status (true - record written, probably)
  */
  public boolean writeMember(Member theRecord, long recordNumber)
  {
    try
    {
       theFile.seek(recordNumber * theRecord.RECORD_LENGTH);
       theFile.writeInt(theRecord.getCode());
       String f = setLength(theRecord.getFirst(), theRecord.FIRST_L);
       String l = setLength(theRecord.getLast(), theRecord.LAST_L);
       theFile.writeChars(f);
       theFile.writeChars(l);
       theFile.writeBoolean(theRecord.hasPaid());
       return true;
    }
    catch(IOException ioe)
    {
       System.out.println("WriteMember: " + ioe.getMessage());
       return false;
    }
  }
  /**
  * This method returns the number of the last record in the file
  * ie if there is one record it will return 0.
  *
  * @return the number of the last record component or -1 on error
  */

  public long numRecords()
  {
    try
    {
      long fLen = theFile.length();
      long rLen = Member.RECORD_LENGTH;
      long num = (fLen / rLen) - 1;
      return num;
    }
    catch(IOException ioe)
    {
      System.out.println("NumRecords: " + ioe.getMessage());
      return -1;
    }
  }
  /**
  * This method adds a record at the end of the file
  *
  * @param the Member record to be written
  */
  public void append(Member theRecord)
  {
    writeMember(theRecord, numRecords() + 1);
  }
  /**
  * This method inserts a record in the file in code order
  *
  * @param the Member record to be written
  * @return the position at which the record was inserted
  */
  public long insert(Member theRecord)
  {
    // pos starts at 1 + number of records
    long pos = numRecords() + 1;
    boolean found = false;
    Member theMember;
    while ( (pos > 0) && (!found) )
    {
      // compare code of record to be inserted with code
      // of current record in the file

      theMember = readMember(pos-1);
      int mem = theMember.getCode();
      int rec = theRecord.getCode();
      if (mem > rec)
      {
        // insertion point found
        found = true;
      }
      else
      {
        // shuffle up current record 1 space
        writeMember(theMember, pos);
        pos = pos - 1;
      }
    }
    // put new record here:
    writeMember(theRecord, pos);
    return pos;
  }
  /**
  * This method searches for a record by ID number
  *
  * @param the Member record to be found
  * @return the position at which the record is located or -1
  */

  public long searchMember(long id)
  {
    long x = 0;
    boolean found = false;
    while( (!found) && (x <= numRecords()) )
    {
      // code mysteriously disappeared (2 lines) !!
      Member theRecord = readMember(x);
      found = (id == theRecord.getCode());
      x++;
    }
    if (found)
    {
      return (x - 1);
    }
    else
    {
      return -1;
    }
  }
  /** This method deletes a record from the file by shuffling over the
  * record at the position secified in the parameter
  *
  * @param the Member record number to be deleted
  */

  public void delete(long pos)
  {
    long last = numRecords();
    Member theRecord;
    // shuffle from here to end of file
    for(long x = (pos + 1); x <= last; x++)
    {
      // code mysteriously disappeared (2 lines) !!
      theRecord = readMember(x);
      writeMember(theRecord, x - 1);
    }
    // truncate the file to remove last duplicate
    try
    {
      long newLength = theFile.length() - Member.RECORD_LENGTH;
      theFile.setLength(newLength);
    }
    catch(IOException ioe)
    {
      System.out.println("Error truncating file: " + ioe.getMessage());
    }
  }
  /**
  * This method forces a String to a set length, needed for
  * fixed length records
  *
  * @param The String to convert
  * @param the lenght to convert to
  */
  private String setLength(String s, int x)
  {
    StringBuffer sb = new StringBuffer(s);
    sb.setLength(x);
    return sb.toString();
  }
  /**
  * This method reads UNICODE chars from the file and truncates
  * them to 8-bit ASCII bytes
  *
  * @param the number of UNICODE chars in this field
  * @return the field as a String
  */

  private String readString(int len)
  {
    try
    {
      byte[] b = new byte[len];
      for(int x = 0; x < len; x++)
      {
        b[x] = (byte) theFile.readChar();
      }
      return new String(b);
    }
    catch(IOException ioe)
    {
      System.out.println("Error reading chars: " + ioe.getMessage());
      return "EEEE";
    }
  }
  /**
  * IBIO methods, (c) International Baccalaureate 2003
  * Computer Science Subject Guide, Appendix 2.
  */

You need to add the IBIO methods here again.

Related: [ Java home | Files home | Previous: Console ]

An actual RAF

 


 
The site is partly financed by advertising revenue, partly by online teaching activities and partly by donations. If you or your organisation feel these resouces have been useful to you, please consider a donation, $9.95 is suggested. Please report any issues with the site, such as broken links, via the feedback page, thanks.

Questions or problems related to this web site should be addressed to Richard Jones who asserts his right to be identified as the author and owner of these materials - unless otherwise indicated. Please feel free to use the material presented here and to create links to it for non-commercial purposes; an acknowledgement of the source is required by the Creative Commons licence. Use of materials from this site is conditional upon your having read the additional terms of use on the about page and the Creative Commons Licence. View privacy policy.

Creative Commons License


This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License. © 2001 - 2009 Richard Jones, PO BOX 246, Cambridge, New Zealand;
This page was last modified: May 31, 2009