rms

9
RMS: Almacenamiento en MIDP OBJETIVOS MIDP define una sencilla base de datos orientada a registros que permite almacenar a las aplicaciones datos de forma persistente. Esta base se denomina Record Management System (RMS). La práctica de hoy tiene como objetivo aprender los conceptos básicos para el manejo de esta base datos, a través del API que nos ofrece MIDP. Todas las clases relacionadas con RMS están contenidas en el paquete javax.microedition.rms. Esta práctica os debe servir para enfrentaros con dos partes de la práctica final: almacenar el estado de una partida, para que sea posible parar y reanudar un partida (opciones del menú Stop y Restart) y para mantener el registro de mejores puntuaciones (opción Records). RecordStore El mecanismo básico de almacenamiento de RMS es denominado record store. Un record store es un conjunto de registros, y un registro es un byte array de datos de tamaño variable. Un record store está representado por un objeto de la clase RecordStore. Existen reglas importantes sobre los record store: 1. El nombre de un record store consiste en una combinación de hasta 32 caracteres (sensible a las mayúsculas). 2. Los record stores creados por MIDlets de un mismo MIDlet suite están almacenados en el mismo espacio de nombres, y por lo tanto, pueden compartir y ver sus contenidos.

Upload: julio-cesar-diaz-carrasco

Post on 03-Aug-2015

14 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Rms

RMS: Almacenamiento en MIDP OBJETIVOS

MIDP define una sencilla base de datos orientada a registros que permite almacenar a las aplicaciones datos de forma persistente. Esta base se denomina Record Management System (RMS). La práctica de hoy tiene como objetivo aprender los conceptos básicos para el manejo de esta base datos, a través del API que nos ofrece MIDP. Todas las clases relacionadas con RMS están contenidas en el paquete javax.microedition.rms. Esta práctica os debe servir para enfrentaros con dos partes de la práctica final: almacenar el estado de una partida, para que sea posible parar y reanudar un partida (opciones del menú Stop y Restart) y para mantener el registro de mejores puntuaciones (opción Records).

 RecordStore

El mecanismo básico de almacenamiento de RMS es denominado record store. Un record store es un conjunto de registros, y un registro es un byte array de datos de tamaño variable. Un record store está representado por un objeto de la clase RecordStore. Existen reglas importantes sobre los record store:

1. El nombre de un record store consiste en una combinación de hasta 32 caracteres (sensible a las mayúsculas).

2. Los record stores creados por MIDlets de un mismo MIDlet suite están almacenados en el mismo espacio de nombres, y por lo tanto, pueden compartir y ver sus contenidos.

3. Los record stores creados por MIDlets en un MIDlet suite, no son accesibles para los MIDltes de otros MIDlets suite.

4. El nombre de un record store debe ser único en un MIDlet suite.

Operaciones con un Record Store

La clase RecordStore proporciona los siguientes métodos para crear, abrir, cerrar y

Page 2: Rms

borrar un record store:

Para crear/abrir un objeto RecordStore se utiliza el método public static RecordStore openRecordStore(String recordName, boolean createIfNecessary:

o Para crearlo se puede utilizar: RecordStore.openRecordStore(recordStoreName, true), de tal forma que si el record store con nombre recordStoreName no existe, se crea. Si existe, se "abre" el existente para trabajar sobre él.

o Para abrirlo también se puede utilizar: RecordStore.openRecordStore(recordStoreName, false), de tal forma que si el record store no existe, se produce una excepción RecordStoreNotFoundException

Para cerrar un objeto RecordStore se utiliza el método public void closeRecordStore. Después de utilizar un record store siempre debe cerrarse.

Para borrar un objeto RecordStore se utiliza el método public static void deleteRecordStore(String recordStoreName). Antes de borrar un record store es necesario cerrarlo.

Cada record store mantiene al menos un campo de cabecera. Si no existe espacio suficente para almacenar la cabecera, el record store no se creará y se producirá una RecordStoreFullException. Si ocurre otro tipo de problema, como que el nombre del record store es demasiado largo, o el record store está corrupto, se produce una RecordStoreException.

A continuación, se puede ver un sencillo ejemplo de creación de un RecordStore (RecordStoreTest1.java).

import javax.microedition.midlet.*;import javax.microedition.rms.*;

public class RecordStoreTest1 extends MIDlet { public RecordStoreTest1() { } public void startApp() throws MIDletStateChangeException { RecordStore rs=null; try {

rs = RecordStore.openRecordStore("file1",true); System.out.println("record store file1 is opened."); }catch(Exception e){

Page 3: Rms

System.out.println("Error: "+e.getMessage()); } finally{ //close the record store try {

rs.closeRecordStore(); System.out.println("record store file1 is closed"); }catch (Exception e){ System.out.println("Error: "+e.getMessage()); } } destroyApp(true); notifyDestroyed(); }

/** * Pause the MIDlet */ public void pauseApp() { }

/** * Called by the framework before the application is unloaded */ public void destroyApp(boolean unconditional) { }}

Records

Los elementos de un record store se denominan records. Los records se representan por arrays de bytes y se identifican univocamente mediante recordIDs (valores enteros que comienzan en 1). Los records pueden se añadidos, borrados, leidos y modificados a través de los siguientes métodos, proporcionados por el API:

public int addRecord(byte[] data, int offset, int numBytes)

public void deleteRecord(int RecordId)

public int getRecord(int recordId, byte[] buffer, int offset) y public byte[] getRecord(int recordId)

public void setRecord(int recordId, byte[] newData, int offset, int numBytes)

A continuación podeis ver un ejemplo sencillo, que partiendo del primer ejemplo,

Page 4: Rms

añade dos records nuevos y borra uno de ellos (RecordStoreTest3.java).

import javax.microedition.midlet.*;import javax.microedition.rms.*;

public class RecordStoreTest3 extends MIDlet { public RecordStoreTest3() { } public void startApp() throws MIDletStateChangeException { RecordStore rs=null; try {

rs = RecordStore.openRecordStore("file1",true); byte data[]= new byte[4]; for(int j=0; j<2; j++) { int i=rs.getNextRecordID(); data[0] = (byte)((i >> 24) & 0xff); data[1] = (byte)((i >> 16) & 0xff); data[2] = (byte)((i >> 8) & 0xff); data[3] = (byte)(i & 0xff); System.out.println("record "+ rs.addRecord(data,0,4)+" is added."); }

try { rs.deleteRecord(2); System.out.println("record 2 is deleted.");

}catch(InvalidRecordIDException e) {System.out.println("record 2 does not exist");

} }catch(Exception e){} finally{ //close the record store try {

rs.closeRecordStore(); }catch (Exception e){} } destroyApp(true); notifyDestroyed(); }

/** * Pause the MIDlet */ public void pauseApp() { }

/** * Called by the framework before the application is unloaded */ public void destroyApp(boolean unconditional) { }}

La cabecera de un Record Store

Los record stores al igual que los ficheros mantienen una cabecera con información propia:

El número de records en el record store. El valor inicial es cero. Cuando se añade un nuevo record, su valor se incrementa en uno. Cuando se elimina un

Page 5: Rms

record su valor se decrementa en uno. Para obtener su valor se utiliza el método public int getNumRecords()

Número de versión. El número de versión inicial depende de la implementación, y normalmente es cero, cada vez que un record es añadido, borrado o modificado, el número de versión se incrementa, normalmente en uno. Para obtener su valor se utiliza el método public int getVersion(). La versión le sirve a los MIDlets para saber si otro proceso o thread ha modificado un determinado record store

El último momento en el que se modificó. Para obtener su valor se utiliza el método public long getLastModified()

El siguiente recordID. El identificador del siguiente record que será añadido. Para obtener su valor se utiliza el método public int getNextRecordID()

El API nos proporciona además la siguiente información adicional sobre los records store, aunque no está almacenada en la cabecera:

public int getSizeAvailable() , que nos permite saber cual es la memoria disponible en bytes, para seguir almacenando en el record store.

public int getSize() , que nos permite saber cuanto espacio ocupa, en bytes, el record store.

public static String[] listRecordStores() , que nos permite obtener en un array de Strings los nombres de los records stores en un MIDlet suite. Si no se ha creado ninguno devuelve null.

El interfaz RecordListener

A través del interfaz RecordListener se pueden monitorizar cambios en record stores. Se pueden gestionar tres tipos de eventos, a través de los métodos:

Page 6: Rms

void recordAdded(RecordStore recordStore, int recordId)

void recordChanged(RecordStore recordStore, int recordId)

void recordDeleted(RecordStore recordStore, int recordId)

La clase RecordStore proporciona los siguientes métodos para añadir o borrar un RecordListener:

public void addRecordListener(RecordListener listener)

public removeRecordListener(RecordListener listener)

NOTA:Un objeto RecordStore puede tener varios RecordListeners registrados.

 RecordEnumeration

Después de que los records se borren, los recordIds de los records que están almacenados en un record store no son consecutivos. Por lo tanto, realizar un recorrido secuencial para obtener todos los records almacenados no es la manera más eficiente de hacerlo.

Para ello se proporciona la clase RecordEnumeration, que aunque en el API de MIDP se presenta como un interfaz, toda implementación de MIDP debe proporcionar una implementación de ella.

Un RecordEnumeration es parecido a un lista doblemente enlazada, en la que cada nodo representa un recordId. Un RecordEnumeration mantiene una secuencia lógica de recordIds de los records almacenados en un record store.

Ejercicio:Analizad el interfaz y realizad un pequeño programa en el que obteneis secuencialmente el contenido de los records en un record store. Cread después un nuevo programa que utilice la implementacion de RecordEnumeration y comprobad la diferencia.

Page 7: Rms

 RecordFilter y RecordComparator

El interfaz RecordFilter define un único método public boolean matches(byte candidate[]) que nos permite definir un criterio para seleccionar un record en un record store que cumpla una determinada condición, de tal forma que si la cumple, se devuelve true y si no false.

El interfaz RecordComparator nos proporciona una forma sencilla de clasificar records. Define una única función int compare(byte[] rec1, byte[] rec2), que puede devolver únicamente los siguientes constantes:

PRECEDES FOLLOWS EQUIVALENT

Por ejemplo, una manera de clasificarlos sería por fecha de creación. Así al implentar esta función se devolvería PRECEDES si rec1 se ha creado antes de rec2, FOLLOWS si se ha creado después y EQUIVALENT si se han creado simultaneamente.