Ộ Ộ

Ậ Ậ

Ế Ế

Ị Ị

L P TRÌNH J2ME CHO THI T B  DI Đ NG L P TRÌNH J2ME CHO THI T B  DI Đ NG

PH N 4ẦPH N 4Ầ

ủ Bãi rác c a anh ^_^

5. Record Management System (RMS) 5. Record Management System (RMS)

 MIDP không s  d ng h  th ng file đ  l u tr  d  li u. Thay vào đó MIDP l u toàn b  thông

ữ ữ ệ ể ư ộ ệ ố

ượ ớ ằ ệ ố ư ư ữ ọ ng vùng nh ) b ng h  th ng l u tr  g i là Record

ử ụ tin vào non­volatile memory (dung l Management System (RMS).

 RMS là h  th ng đ

ệ ố ỗ ả ướ ạ ượ ổ ứ c t ch c và qu n lý d ỗ ự ả ộ ả ể ứ ấ ỳ ạ ữ ệ

ộ ạ ả ả ể ố ế

ạ ỗ ể ư ữ ữ ệ

ợ ầ ượ c vu t quá gi i d  li u ban đ u. Kích th c d  li u không đ ỗ ồ ư ữ ệ i d ng các record (b n ghi). M i b n ghi có  ả ủ ộ ế , m t  nh và k t qu  c a m t  ị i d ng nh  phân  ụ  Record và khôi ph c  ế ị ủ t b   ạ i ằ ướ ữ ệ ầ ấ

 M t t p các b n ghi(RecordStore) là t p h p các Record đ ộ ộ ậ

ậ ộ ậ th  ch a b t k  lo i d  li u nào:ki u s  nguyên, chu i ký t ữ ệ ủ ạ ướ ạ Record là m t chu i (m ng) các byte. N u b n mã hoá d  li u c a b n d ọ ữ ệ ừ (binary), b n có th  l u tr  d  li u b ng Record sau đó đ c d  li u t ớ ạ ạ ữ ệ ị l i h n qui đ nh c a thi ề ư ộ ơ ở ữ ệ ộ di đ ng. RMS l u d  li u g n nh  m t c  s  d  li u, bao g m nhi u dòng, m i dòng l ộ ố ị có m t s  đ nh danh duy nh t.  ả ượ ắ ứ ự ế c s p x p có th  t ỗ . M i ể ứ ộ

ả ạ ộ

ợ ả ứ ể ố ộ ố ị ượ ầ c gán m t s  đ nh danh ki u s  nguyên g i là Record ID. Record đ u tiên đ ế ẽ

ỉ ụ ẽ

ủ ủ ệ ổ

ớ ẽ ụ ộ ộ

ệ ộ

ẽ ượ ế

ụ ể ỉ

ớ ủ ạ ằ ộ ủ ộ c s  d ng cũng phân bi ế ứ ệ ẫ t l n nhau b ng các tên. Tên c a RecordStore có  ấ ượ ử ụ ự ể ộ Unicode và là duy nh t trong m t MIDlet suite.

Record không th  đ ng đ c l p mà nó ph i thu c vào m t RecordStore nào đó, các thao tác  trên Record ph i thông qua RecordStore ch a nó. Khi t o ra m t Record trong RecordStore,  ượ ọ Record đ c  ẽ ượ ạ c gán Record ID là 1,s  tăng thêm 1 cho các Record ti p theo. Record ID không  t o ra s  đ ạ i các  là ch  m c (index), các thao tác xóa Record trong RecordStore s  không tính toán l ượ ạ c t o  Record ID c a các Record hi n có cũng không thay đ i Record ID c a các Record đ ớ ạ m i, ví d : xóa record id 3, thêm m t record m i s  có id là 4. Data là m t dãy các byte đ i  ữ ệ ầ ư ệ di n cho d  li u c n l u. ể ượ t các RecordStore trong b  các MIDlet (MIDlet suite). MIDlet  c dung đ  phân bi Tên đ ư ậ suite là t p các MIDlet có chung không gian tên (name space), chia s  cùng tài nguyên (nh   c đóng  RecordStore), các bi n tĩnh (static variable) trong các l p và các MIDlet này s  đ gói trong cùng m t file khi tri n khai. N u  ng d ng c a b n ch  có m t MIDlet thì các  RecordStore đ ế th  dài đ n 32 ký t

2

ế ế

ữ ủ

ấ ấ ế ề

ượ

ớ ng vùng nh

Dung l

ề ề ả  H n ch  v  kh  năng l u tr  c a thi

t b  di đ ng :  ữ ữ ệ

ặ ả

ế ị

ế ị

MIDP yêu c u r ng các nhà s n xu t thi

ầ ằ ấ

ữ ữ ệ

ướ

ả ệ ư c ít nh t 8K cho vi c l u tr  d  li u trong

ặ ả

ể i h n trên cho m i Record. RMS cung c p các API đ

không nêu gi ướ ủ

ượ

c c a m i Record, t ng dung l

ướ

ệ ử ụ

Các v n đ  liên quan đ n RMS Các v n đ  liên quan đ n RMS    ế ị ư ạ ổ ệ ư (non­volatile memory) dành riêng cho vi c l u tr  d  li u trong RMS thay đ i tùy  ộ theo thi t b  di đ ng. Đ c t t b  di đ ng  ả ph i dành ra vùng nh  có kích th ớ ạ RMS. Đ c t ỗ ị xác đ nh kích th ng c a RecordStore và kích  ớ ạ ủ i c a vùng nh  này. Do đó trong quá trình phát tri n các  ng d ng  c còn l th ả ạ J2ME b n ph i cân nh c trong vi c s  d ng vùng nh  này.

ố ộ

ấ ữ ệ Các thao tác trên vùng nh  này s  ch m h n nhi u khi

ớ ư ố ộ ọ ổ ứ ườ

ấ ữ ệ ủ

 T c đ  truy xu t d  li u : ớ  RAM c a máy tính. Trong k  thu t l p trình ph i th

ố ậ ậ ỉ ự

ả ệ ậ

ộ ầ

ế

ơ ẽ ậ ố ộ ọ  c ng và t c đ  đ c  truy xu t d  li u trên b  nh  RAM. Gi ng nh  t c đ  đ c  ữ ệ ừ t ng xuyên cache d  li u  ở ộ và các thao tác liên quan đ n RMS ch  th c hi n t p trung m t l n (lúc kh i đ ng  ứ hay đóng  ng d ng)

.

ơ ế ồ

ỉ ượ ử ụ

ế

N u RecordStore ch  đ

 C  ch  lu ng an toàn : ả

c s  d ng b i m t MIDlet,  ệ

ể ự

ẻ ộ

ẽ ế

ể ả

ế

không ph i lo l ng vì RMS s  dành riêng m t Thread đ  th c hi n các thao tác  ề trên RecordStore. Tuy nhiên n u có nhi u MIDlet và Thread cùng chia s  m t  ự ậ ậ RecordStore thì ph i chú ý đ n k  thu t l p trình Thread đ  đ m b o không có s   ộ ữ ệ   xung đ t d  li u

3

Các hàm API trong RMS (1)   Các hàm API trong RMS (1)

 RecordStore không có hàm kh i t o.

ở ạ

ư ồ ạ ở ộ ế i.

ỉ  duy nh  Ví d : chụ ố ượ private RecordStore rs = null;  static final String REC_STORE = "db_1";  private void db(String str) {

RecordStore Class: javax.microedition.rms.RecordStore  static RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary) :  ố ạ M  m t Recordstore, có tham s  t o Record store n u nó ch a t n t ở ượ ạ ề ầ ặ ấ c t o m c dù m  nhi u l n cùng 1 tên ng RecordStore đ t 1 đ i t

System.err.println("Msg: " + str);

} }

public void openRecStore() {

try { // Create record store if it does not exist      rs = RecordStore.openRecordStore(REC_STORE, true ); } catch (Exception e) {

db(e.toString());

} }

ư ồ ạ ẽ ạ ế ớ ố ộ V i tham s  true, hàm s  t o m t RecordStore n u nó ch a t n t i.

4

Các hàm API trong RMS (2) Các hàm API trong RMS (2)

 Ví d :ụ private RecordStore rs = null;  public void closeRecStore() {

void closeRecordStore() : Đóng RecordStore

try{

rs.closeRecordStore();

} catch (Exception e) {

db(e.toString());

ả ề  v

} }

 Ví d :ụ public void deleteRecStore() {

ủ ả ỗ static void deleteRecordStore(String recordStoreName) : Xóa RecordStore  static String[] listRecordStores() : Danh sách các RecordStore trong MIDlet suite, tr m ng các chu i là tên c a RecordStore, n u không có RecordStore nào thì tr  v  null  ả ề ế

if (RecordStore.listRecordStores() != null){

try {      RecordStore.deleteRecordStore(REC_STORE); } catch (Exception e) {

db(e.toString());

}

}}

5

Các hàm API trong RMS (3) Các hàm API trong RMS (3)

 int addRecord(byte[] data, int offset, int numBytes):Thêm m t record vào

RecordStore

 Ví d :ụ public void writeRecord(String str) {

byte[] rec = str.getBytes(); try {

rs.addRecord(rec, 0, rec.length);

} catch (Exception e) {

db(e.toString());

} }

ư

ướ

c khi l u vào RecordStore, c n ph i chuy n đ i ki u string thành dãy byte

ố ầ

ế

ể Tr byte[] rec = str.getBytes(); rs.addRecord(rec, 0, rec.length);  ỗ  Có th  thêm m t Record r ng vào RecordStore n u tham s  đ u tiên là  ắ ầ

ộ ế ị

t v  trí b t đ u trong m ng các byte và tham s  th  3 cho bi

null. Tham  ế ố t s

ố ứ ươ

ẽ ượ

ế c ghi vào RecordStore. N u th c hi n thành công, ph

ả ng th c này tr

ỉ ố

ể ố ứ s  th  2 cho bi ệ byte s  đ ừ ượ ề ố v  s  nguyên ch  s  recordID c a Record v a đ

c thêm vào.

6

Các hàm API trong RMS (4) Các hàm API trong RMS (4)

 int getRecord(int recordId, byte[] buffer, int offset) : L y n i dung c a record vào

ố ượ

dãy byte. int getNumRecords() : S  l

ng các record.

 Ví d :ụ

public void readRecords() {

try {    byte[] recData = new byte[50];    int len;    for (int i = 1; i <= rs.getNumRecords(); i++){      len = rs.getRecord( i, recData, 0 );      System.out.println("Record #" + i + ": " +new String(recData, 0, len));      System.out.println("­­­­­­­­­­­­­­­­­­­­");

}

}

catch (Exception e) { db(e.toString()); }

}

7

 Trong ví d  trên do bi

ướ ủ ụ c c a string nên khai báo dãy byte v a đ , trong

c kích th ướ ủ ể ể ầ ế ể c c a record đ  khai báo dãy byte c n thi ừ ủ t đ  tránh phát

ể ử ạ

Các hàm API trong RMS (5) Các hàm API trong RMS (5) ế ướ t tr  ta nên ki m tra kích th i, do đó hàm ReadRecord có th  s a l

ự ế th c t ỗ sinh l ư i nh  sau:

public void readRecords() {

try {

int len;

for (int i = 1; i <= rs.getNumRecords(); i++) {

if (rs.getRecordSize(i) > recData.length)  recData = new byte[rs.getRecordSize(i)];  len = rs.getRecord(i, recData, 0);  System.out.println("Record #" + i + ": " +  new String(recData, 0, len));  System.out.println("­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­");

}

}

catch (Exception e) {           db(e.toString()); }

}

8

ụ ọ ụ ọ

ố ượ ố ượ

Ví d  : đ c và ghi đ i t Ví d  : đ c và ghi đ i t

ng string (ReadWrite.java)  ng string (ReadWrite.java)

(1)(1)

import java.io.*; import javax.microedition.midlet.*; import javax.microedition.rms.*; public class ReadWrite extends MIDlet { private RecordStore rs = null; static final String REC_STORE = "db_1"; public ReadWrite() {

ọ ế

ạ openRecStore(); // t o record store t vào record và đ c chúng ra // vi writeRecord("J2ME and MIDP"); writeRecord("Wireless Technology"); readRecords(); closeRecStore(); // đóng record store deleteRecStore(); // Xoá record store

} public void destroyApp( boolean unconditional ){} public void startApp() { // There is no user interface, go ahead and shutdown destroyApp(false); notifyDestroyed(); } public void pauseApp(){ }

9

ụ ọ ụ ọ

ố ượ ố ượ

Ví d  : đ c và ghi đ i t Ví d  : đ c và ghi đ i t

ng string (ReadWrite.java)  ng string (ReadWrite.java)

(2)(2)

public void openRecStore() {

try {         // Create record store if it does not exist      rs = RecordStore.openRecordStore(REC_STORE, true ); } catch (Exception e) {

db(e.toString());

} }

public void closeRecStore() {

try {

rs.closeRecordStore();

} catch (Exception e) {

db(e.toString());

}  }

public void deleteRecStore() {

if (RecordStore.listRecordStores() != null) {

try {

RecordStore.deleteRecordStore(REC_STORE);

} catch (Exception e) {

db(e.toString());

} } }

public void writeRecord(String str) {

byte[] rec = str.getBytes(); try  {

rs.addRecord(rec, 0, rec.length);

} catch (Exception e) {

db(e.toString());

}  }

10

ụ ọ ụ ọ

ố ượ ố ượ

Ví d  : đ c và ghi đ i t Ví d  : đ c và ghi đ i t

ng string (ReadWrite.java)  ng string (ReadWrite.java)

(3)(3)

 public void readRecords() {

try {

byte[] recData = new byte[50]; int len; for (int i = 1; i <= rs.getNumRecords(); i++) {

len = rs.getRecord( i, recData, 0 ); System.out.println("Record #" + i + ": " + new String(recData, 0, len)); System.out.println("­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­");

}

} catch (Exception e) {

db(e.toString());

}

} private void db(String str){

System.err.println("Msg: " + str);

}

}

ự  Th c hi n:

ệ ReadWrite ReadWrite

11

ả ả

ữ ữ

Chuy n đ i d  li u gi a Record và M ng các byte (1) Chuy n đ i d  li u gi a Record và M ng các byte (1)

ứ ả ộ

ữ ỗ

ư ữ ệ ữ ể ữ ệ ầ ả ả

ữ ữ ệ ố ượ ả

ể ổ ữ ệ ể ổ ữ ệ ụ ư ỗ c RMS l u tr  trong các Record là m t chu i (m ng) các byte. Trong  ng d ng,  ự ậ ộ ố ề .V y  ấ ể ữ ệ c khi l u d  li u vào Record c n ph i chuy n d  li u này thành m ng các byte. V n  ọ ữ ệ ư ng trung gian giúp vi c l u tr  d  li u vào Record và đ c d   ớ ả ệ ễ

ậ ấ ộ

ổ ữ ệ ừ ể ễ ệ  J2SE d  dàng trong vi c chuy n đ i d  li u c th a h ứ ữ ạ

ừ ưở i gi a RMS và  ng d ng trong gói  ể ả ồ

ộ ữ ệ ụ ọ ộ ễ ộ ấ ứ ữ ệ ượ  D  li u đ ạ ố ư b n mu n l u tr  nhi u ki u d  li u khác nhau: m t s  nguyên hay là chu i các ký t ướ tr ề đ  là ph i tìm ra các đ i t ệ ệ ừ li u t  các Record m t cách d  dàng, thu n ti n và hi u qu . CLDC cung c p các l p:  java.io.ByteArrayInputStream, java.io.ByteArrayOutputStream, java.io.DataInputStream,  ượ java.io.DataOutputStream đ ng t ụ java.io. qua l ổ  L p ớ java.io.ByteArrayInputStream chuy n đ i m t m ng các byte thành m t lu ng vào(input  ng th c thao tác d  li u trên nó m t cách d  dàng. Ví d  đ c ị ả ấ ả ươ t c  các giá tr  trong m ng các byte.

stream), và cung c p các ph và in ra t byte[] data = new byte[]{ 1, 2, 3 }; ByteArrayInputStream bin = new ByteArrayInputStream( data ); int b; while( ( b = bin.read() ) != ­1 ){       System.out.println( b ); } try {     bin.close(); } catch( IOException e ){}

12

ể ổ ữ ệ ể ổ ữ ệ

ữ ữ

ả ả

Chuy n đ i d  li u gi a Record và M ng các byte (2) Chuy n đ i d  li u gi a Record và M ng các byte (2)

ữ ệ

ế

 L p ớ java.io.ByteArrayOutputStream :ghi d  li u ki u byte lên m ng các byte. Ví  ByteArrayOutStream ba giá tr  1, 2, 3 liên ti p sau đó xu t ra m ng các

ụ d  ghi vào  byte.

ByteArrayOutputStream bout = new ByteArrayOutputStream();

bout.write( 1 );    bout.write( 2 );    bout.write( 3 );

byte[] data = bout.toByteArray();

for( int i = 0; i < data.length; ++i ){

System.out.println( data[i] );

}

try {

bout.close();

} catch( IOException e ){

ỏ ọ ệ // b  qua các ng ai l

ữ ệ

ươ

ấ ả ữ ệ

 B  đ m (buffer) c a  ng th c

ẽ ự ộ ủ ByteArrayOutStream s  t ẽ ứ toByteArray() c a nó s  chép t

đ ng tăng d n lên khi ghi d  li u  t c  d  li u lên m ng các  13

ộ ệ lên nó, ph byte.

}

ể ơ ả ể ơ ả Ghi d  li u ki u c  b n trên Record Ghi d  li u ki u c  b n trên Record ộ ữ ệ

ể ơ ả ự ệ ằ ớ

ữ ệ ữ ệ  Ghi d  li u có các ki u c  b n nh

ư int, long, String lên m t Record th c hi n b ng các l p

java.io.ByteArrayOutputStream và java.io.DataOutputStream.

private RecordStore rs = null;  public void writeStream(String[] sData, boolean[] bData, int[] iData) {     try {// Write data into an internal byte array       ByteArrayOutputStream strmBytes = new ByteArrayOutputStream();       DataOutputStream strmDataType = new DataOutputStream(strmBytes);        byte[] record;       for (int i = 0; i < sData.length; i++) {    // Write Java data types          strmDataType.writeUTF(sData[i]);      strmDataType.writeBoolean(bData[i]);         strmDataType.writeInt(iData[i]);          strmDataType.flush(); // Clear any buffered data         record = strmBytes.toByteArray(); // Get stream data into byte array and write record         rs.addRecord(record, 0, record.length);               strmBytes.reset();  }         strmBytes.close();    strmDataType.close(); }     catch (Exception e) {         db(e.toString());  }  }

14

ọ ữ ệ ọ ữ ệ

ượ ạ ằ ọ ữ ệ ừ

ể ơ ả ể ơ ả Đ c d  li u ki u c  b n trên Record Đ c d  li u ki u c  b n trên Record c l

 Đ c d  li u t

i b ng các l p ớ java.io.ByteArrayInputStream và Record ng java.io.DataInputStream.

public void readStream() {

// Careful: Make sure this is big enough!Better yet, test and reallocate if necessary byte[] recData = new byte[50]; // Read from the specified byte array ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData); // Read Java data types from the above byte array DataInputStream strmDataType = new DataInputStream(strmBytes);  for (int i = 1; i <= rs.getNumRecords(); i++){ // Get data into the byte array

try {

rs.getRecord(i, recData, 0); // Read back the data types   System.out.println("Record #" + i);

System.out.println("UTF: " + strmDataType.readUTF());    System.out.println("Boolean: " +strmDataType.readBoolean());    System.out.println("Int: " + strmDataType.readInt());    System.out.println("­­­­­­­­­­­­­­­­­­­­");    strmBytes.reset(); // Reset so read starts at beginning of array

}    strmBytes.close();    strmDataType.close(); } catch (Exception e){

db(e.toString()); } }

15

ọ ử ụ ọ ử ụ Ghi và đ c s  d ng stream  Ghi và đ c s  d ng stream  ượ

ướ

ữ ệ  Quá trình ghi d  li u vào RecordStore đ

c th c hi n thông qua các b

c:

• C p phát stream. ữ ệ • Ghi d  li u vào stream. • Flush stream. ể • Chuy n đ i stream data thành m ng byte. ả • Ghi m ng byte vào RecordStore. • Đóng stream.

ả ọ

 Khi s  d ng DataOutputStream và DataInputStream, c n ph i đ c và ghi theo đúng

ế

th  t

ử ụ ố   ứ ự ế , n u không s  không ra k t qu  mong mu n

ReadWriteStreams  Ví d : ụ ReadWriteStreams

16

ớ ớ

ệ ệ

Duy t Record v i RecordEnumeration  Duy t Record v i RecordEnumeration

 L p này cung c p các ph ướ

ươ ộ ớ ấ ng th c đ  duy t các record trong RecordStore m t cách nhanh

ạ ứ ể ệ ệ ộ

 RecordEnumeration Interface: javax.microedition.rms.RecordEnumeration

chóng. D i đây là đo n code duy t toàn b  RecordStore: RecordEnumeration re = rs.enumerateRecords(null,null,false); while (re.hasNextElement()) {  // Get the next record into a String String str = new String(re.nextRecord()); ... .. }

ố ượ ng record trong enumeration

ế

ế

c đó

ướ ủ ướ c đó

c đó

ự ộ ể đ ng reindex()

ạ ạ

ư ề

ả ầ ở c s  d ng b i enumeration i phóng tài nguyên đ

int numRecords() : S  l byte[] nextRecord():  Record ti p theo ủ int nextRecordId() : Record ID c a record ti p theo byte[] previousRecord():  Record tr int previousRecordId() : Record ID c a record tr ế ế boolean hasNextElement() : Ki m tra enumeration có record k  ti p ướ ể boolean hasPreviousElement() : Ki m tra enumeration có record tr ổ ặ void keepUpdated(boolean keepUpdated): Đ t enumeration reindex sau khi co s  thay đ i boolean isKeptUpdated() : Ki m tra enumeration có t void rebuild() : T o l i index void reset() : Đ a enumeration v  record đ u tiên ượ ử ụ void destroy() : Gi

17

ắ ế ắ ế

ớ ớ

S p x p các record v i interface RecordComparator  S p x p các record v i interface RecordComparator

(1)  (1)

ươ

ị  Interface đ nh nghĩa ph

ể ng th c compare v i tr  đ u là hai m ng các byte th

ị ượ ị

ươ

ớ ị ầ ả ề ng th c này tr  v  các tr  đ

c đ nh nghĩa trong

ế

ứ ứ

ứ ứ

ế ế

ướ

c Record th  2 ầ ử ụ

ứ hi n hai Record c n so sánh. Ph interface: •EQUIVALENT: N u hai Record b ng nhau •FOLLOWS: N u Record th  1 đ ng sau Record th  2 ứ •PRECEDES: N u Record th  1 đ ng tr Do RecordComparator là m t interface nên khi s  d ng c n ph i implements nó:

 public class Comparator implements RecordComparator {

public int compare(byte[] rec1, byte[] rec2){ String str1 = new String(rec1), str2 = new String(rec2); int result = str1.compareTo(str2); if (result == 0) return RecordComparator.EQUIVALENT; else if (result < 0) return RecordComparator.PRECEDES; else return RecordComparator.FOLLOWS; } }

18

ắ ế ắ ế

ớ ớ

S p x p các record v i interface RecordComparator  S p x p các record v i interface RecordComparator

(2)(2)

 Trong hàm readRecord(), khi t o Enumeration ta đã tham chi u đ n đ i t

ố ượ

ế ế ẽ ử ụ ạ ạ ủ ớ ng comp c a l p  ở  trên

ế ạ hàm String.CompareTo() )

Comparator, khi enumerator t o index cho RecordStore nó s  s  d ng hàm compare()  ể ắ đ  s p x p các record (record là d ng text ­  public void readRecords() {

try  {       if (rs.getNumRecords() > 0){         Comparator comp = new Comparator();         RecordEnumeration re = rs.enumerateRecords(null, comp, false);         while (re.hasNextElement()) {           // Calls String constructor that takes an array of bytes as input           String str = new String(re.nextRecord());           System.out.println(str);           System.out.println("­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­");                                 }}}     catch (Exception e){       db(e.toString());     }} SimpleSort  Ví d : ụ SimpleSort

19

ể ơ ả ể ơ ả

ớ ữ ệ ớ ữ ệ

ắ ế ắ ế

S p x p các record v i d  li u ki u c  b n S p x p các record v i d  li u ki u c  b n

 N u ghi nhi u ki u d  li u vào trong m t record:

ể ữ ệ ề ế ộ

strmDataType.writeUTF("Text 1"); strmDataType.writeBoolean(true); strmDataType.writeInt(1);

 Các ki u d  li u s  l u vào m t stream d ng binary. Các stream này đ

ể ữ ệ ẽ ư ạ ượ ể c chuy n thành

ư ả

ộ m ng và đ a vào recordstore: record = strmBytes.toByteArray(); rs.addRecord(record, 0, record.length);

ớ ự ứ ổ

ỗ ế ệ i hàm compare() th  c hi n ch c năng chuy n đ i  ế ể ể ắ

ể ữ ệ  V i ki u d  li u binary ta ph i vi ắ ề ể ữ ệ ứ

ả ế ạ t l ự ể ữ ệ chu i byte và s p x p đúng ki u d  li u. Th c thi interface RecordComparator đ  s p x p  ữ ệ ẽ ư record ch a nhi u ki u d  li u. Đây là d  li u s  l u vào recordstore: String[] names = {"Thu", "Hanh", "Yen", "Khanh","Anh"};    boolean[] sex = {false,true, false, true,true};        int[] rank = {2, 0, 4, 3,1};

 Khi l u vào recordstore s  có d ng nh  sau:

ư ẽ ạ

ư Record #1 Name : Anh Sex : Male Rank : 1

20

ớ ữ ệ ớ ữ ệ

ể ể

S p x p các record v i d  li u ki u String (1)  S p x p các record v i d  li u ki u String (1)

ắ ế ắ ế public void readStream() {

try {     byte[] recData = new byte[50];     ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData);     DataInputStream strmDataType = new DataInputStream(strmBytes);     if (rs.getNumRecords() > 0) {

ComparatorString comp = new ComparatorString();    int i = 1; RecordEnumeration re = rs.enumerateRecords(null,comp, false); while (re.hasNextElement()){

rs.getRecord(re.nextRecordId(), recData, 0); System.out.println("Record #" + i++); System.out.println("Name: " + strmDataType.readUTF()); if (strmDataType.readBoolean())     System.out.println("Sex: Male"); else     System.out.println("Sex: Female" ); System.out.println("Rank: " + strmDataType.readInt()); System.out.println("­­­­­­­­­­­­­­­­­­­­"); strmBytes.reset();} comp.compareStringClose();   re.destroy(); } strmBytes.close();      strmDataType.close(); }

catch (Exception e) { db(e.toString()); }}

21

ớ ữ ệ ớ ữ ệ

S p x p các record v i d  li u ki u String (2) S p x p các record v i d  li u ki u String (2)

ể ể if (maxsize > recData.length)     recData = new byte[maxsize]; // Read record #1Only need one read because the  string //to sort on is the first "field" in the record  strmBytes = new ByteArrayInputStream(rec1);

ắ ế ắ ế class ComparatorString implements  RecordComparator { private byte[] recData = new byte[10]; // Read from a specified byte array private ByteArrayInputStream strmBytes = null; private DataInputStream strmDataType = null; public void compareStringClose() {   try {

if (strmBytes != null) strmBytes.close(); if (strmDataType != null) strmDataType.close();}

catch (Exception e) {} }

strmDataType = new DataInputStream(strmBytes); str1 = strmDataType.readUTF(); // Read record #2 strmBytes = new ByteArrayInputStream(rec2); trmDataType = new DataInputStream(strmBytes); str2 = strmDataType.readUTF(); // Compare record #1 and #2 int result = str1.compareTo(str2); if (result == 0) return RecordComparator.EQUIVALENT; else if (result < 0) return RecordComparator.PRECEDES;         else return RecordComparator.FOLLOWS; }     catch (Exception e) { return RecordComparator.EQUIVALENT;

}}}

public int compare(byte[] rec1, byte[] rec2 {     String str1, str2;     try { // If either record is larger than our buffer, reallocate int maxsize = Math.max(rec1.length, rec2.length);

22

ể ể

ắ ế ắ ế

ớ ữ ệ ớ ữ ệ

ng d  li u đ u tiên trong các record là ki u string, ­ dùng làm tiêu chí s p

ỗ ầ

ữ ệ ể ướ ế c h t ta l y chu i c n so sánh trong dãy byte b ng hàm readUTF() , r i  ế

ể ắ

S p x p các record v i d  li u ki u String (3) S p x p các record v i d  li u ki u String (3) ườ  Tr ế x p. Tr dùng compareTo() trong class String đ  s p x p: // Read record #1 str1 = strmDataType.readUTF(); // Read record #2 . . . str2 = strmDataType.readUTF(); // Compare record #1 and #2 int result = str1.compareTo(str2);

 Ví d : ụ StringSort StringSort

23

S p x p các record v i ki u integer,  Ví d : ụVí d : ụ IntSort S p x p các record v i ki u integer,  IntSort ố

ớ ể ớ ể ữ ệ

ể ả ọ

ằ ớ ế

ầ ấ ồ

ả ọ

ứ ự

 Tiêu chí s p x p là theo ki u integer, d  li u ta c n l y n m cu i cùng trong dãy byte do đó c n  , ph i đ c ki u String, boolean r i m i đ n integer:

ắ ế ắ ế ế ắ ph i đ c theo th  t

public int compare(byte[] rec1, byte[] rec2) {

int x1, x2; try {// If either record is larger than our buffer, reallocate  int maxsize = Math.max(rec1.length, rec2.length); if (maxsize > recData.length) recData = new byte[maxsize]; // Read record #1  we must read the String and boolean to get to the integer strmBytes = new ByteArrayInputStream(rec1); strmDataType = new DataInputStream(strmBytes); strmDataType.readUTF(); strmDataType.readBoolean(); x1 = strmDataType.readInt(); // Here's our data // Read record #2 strmBytes = new ByteArrayInputStream(rec2); strmDataType = new DataInputStream(strmBytes); strmDataType.readUTF();  strmDataType.readBoolean(); x2 = strmDataType.readInt(); // Here's our data if (x1 == x2) // Compare record #1 and #2 return RecordComparator.EQUIVALENT; else if (x1 < x2) return RecordComparator.PRECEDES; else return RecordComparator.FOLLOWS; } catch (Exception e) { return RecordComparator.EQUIVALENT; } }

24

Searching with RecordFilter (1) Searching with RecordFilter (1)

ệ ế ỏ

ề ượ ư ộ ộ t c  các record trong RecordStore đ u đ

ớ ấ ơ ế ọ ử ề enumerator cung c p c  ch  l c (tìm ki m các record th a mãn m t đi u ki n nào đó). S   ấ ả ụ d ng RecordComparator t c l u trong m t result  ệ ề ỏ set. Dùng RecordFilter, th a đi u ki n m i trong enumerator result set.

class SearchFilter implements RecordFilter { private String searchText = null; public SearchFilter(String searchText) { this.searchText = searchText.toLowerCase(); // This is the text to search for } public boolean matches(byte[] candidate) { String str = new String(candidate).toLowerCase(); if (searchText != null && str.indexOf(searchText) != ­1) // Look for a match return true; else return false; } }

 Class RecordFilter đ

ệ ế ớ ộ c g n v i m t enumerator, nó dùng hàm matches() duy t h t

ầ ấ ượ ắ ữ recordstore l y ra nh ng record c n tìm:

SearchFilter search = new SearchFilter("search text"); // Create a new search filter

ề ộ ỏ

// Reference the filter when creating the result set RecordEnumeration re = rs.enumerateRecords(search,null,false); ế boolean matches(byte[] candidate) : Tìm ki m record th a mãn m t đi u ki n nào đó ệ 25

Searching with RecordFilter (2) Searching with RecordFilter (2)

 public SimpleSearch() {

display = Display.getDisplay(this); // Define textfield, stringItem and commands tfFind = new TextField("Find", "", 10, TextField.ANY); siMatch = new StringItem(null, null); cmExit = new Command("Exit", Command.EXIT, 1); cmFind = new Command("Find", Command.SCREEN, 2); // Create the form, add commands fmMain = new Form("Record Search"); fmMain.addCommand(cmExit); fmMain.addCommand(cmFind); // Append textfield and stringItem fmMain.append(tfFind); fmMain.append(siMatch); // Capture events fmMain.setCommandListener(this); // Open and write to record store openRecStore(); // Create the record store writeTestData(); // Write a series of records }

26

Searching with RecordFilter (3), Ví d : ụVí d : ụ SimpleSearch Searching with RecordFilter (3),  SimpleSearch

private void searchRecordStore() {

try {// Record store is not empty if (rs.getNumRecords() > 0){// Setup the search filter with the user requested text      SearchFilter search = new SearchFilter(tfFind.getString());

RecordEnumeration re = rs.enumerateRecords(search, null, false);     if (re.numRecords() > 0) // A match was found using the filter     siMatch.setText(new String(re.nextRecord())); // Show match in the stringItem on the form      re.destroy(); // Free enumerator

} } catch (Exception e) {

db(e.toString()); } }

class SearchFilter implements RecordFilter { private String searchText = null; public SearchFilter(String searchText) {    this.searchText = searchText.toLowerCase(); // This is the text to search for  } public boolean matches(byte[] candidate) {

String str = new String(candidate).toLowerCase(); if (searchText != null && str.indexOf(searchText) != ­1) // Look for a match

return true;

else

return false;

} }

27

(1) SearchStreams (1) ườ

ư

Searching with RecordFilter – SearchStreams Searching with RecordFilter –  ạ ữ ệ ư  D  li u l u vào record d ng dãy byte, trong dãy byte l u nhi u tr

ữ ệ ng d  li u:

strmDataType.writeUTF(sData); // Write Strings strmDataType.writeBoolean(bData); // Write booleans strmDataType.writeInt(iData); // Write integers

ạ  Trong hàm searchRecordStore() ta t o m t b  tìm ki m và enumerator. Ph ượ

ế ộ ộ ẽ ượ ọ ở ể ọ ượ

ươ ng  c g i b i enumerator và đ c áp  ữ ệ ầ c đúng d  li u c n dùng ta  ể ọ ộ

ể ọ

ể ữ ệ

ứ th c matches() (c a class SearchFilter) s  đ ụ d ng cho m i record trong RecordStore. Đ  đ c đ ộ ầ c n dùng hai stream – m t dùng đ  đ c dãy byte trong record và m t dùng đ  đ c  đúng ki u d  li u trong dãy byte đó. strmBytes = new ByteArrayInputStream(candidate); strmDataType = new DataInputStream(strmBytes); str = strmDataType.readUTF().toLowerCase();

ẽ ượ

 Sau đó chu i này s  đ

ớ c so sánh v i searchText:

if (str != null && str.indexOf(searchText) != ­1) return true; else return false;

28

Searching with RecordFilter – SearchStreams Searching with RecordFilter –

(2) SearchStreams (2)

public void writeTestData() {

String[] names = {"Lan : Lop C04 CNTT HVCNBCVT",                      "Thu : K45 CNTT Dai Hoc Bach Khoa HN",                      "Hoai Anh : K39 QTDN Truong Kinh Te Quoc Dan",                      "Yen Chi : Lop Anh Ngu Truong Dai Hoc Ngoai Ngu HN"};    boolean[] sex = {true, false, true, true};        int[] rank = {3, 0, 1, 2};    writeStream(names, sex, rank);  }  private void searchRecordStore()  {

try {    // Record store is not empty       if (rs.getNumRecords() > 0) {// Setup the search filter with the user requested text       SearchFilter search =  new SearchFilter(tfFind.getString());         RecordEnumeration re =                rs.enumerateRecords(search, null, false);                if (re.numRecords() > 0)      // A match was found using the filter          {                  // Read from the specified byte array

29

(3) SearchStreams (3) Searching with RecordFilter – SearchStreams Searching with RecordFilter –  ByteArrayInputStream strmBytes =   new ByteArrayInputStream(re.nextRecord()); DataInputStream strmDataType =  new DataInputStream(strmBytes); // Read Java data types from

the above byte array

siMatch.setText(strmDataType.readUTF()); // Show matching result in stringItem component on form           search.searchFilterClose(); // Close record filter           strmBytes.close();          // Close stream           strmDataType.close();       // Close stream           re.destroy();               // Free enumerator         }   }   }     catch (Exception e)  {       db(e.toString());     } }

30