
Page 21
T ng b c l p trình :ừ ướ ậ
CHO ĐI N THO I DI Đ NG J2ME (ph n Ệ Ạ Ộ ầ 4)
Lê Ng c Qu c Khánhọ ố
1 L u tr b n ghi (Record Store)ư ữ ả
L u tr b n ghi cho phép l u d li u khi ng d ng thoát, kh i đ ng l i và khi thi t b diư ữ ả ư ữ ệ ứ ụ ở ộ ạ ế ị
đ ng t t hay thay pin. D li u l u tr b n ghi s t n t i trên thi t b di đ ng cho đ n khi ngộ ắ ữ ệ ư ữ ả ẽ ồ ạ ế ị ộ ế ứ
d ng th t s đ c xóa kh i thi t b di đ ng. Khi m t MIDlet b xóa, t t c các l u tr b nụ ậ ự ượ ỏ ế ị ộ ộ ị ấ ả ư ữ ả
ghi c a nó cũng b xóa.ủ ị
Hình 1 minh h a d li u l u tr b n ghi v i MIDletọ ữ ệ ư ữ ả ớ
Nh trong hình, các MIDlet có th có nhi u h n m t t p l u tr b n ghi, chúng ch có thư ể ề ơ ộ ậ ư ữ ả ỉ ể
truy xu t d li u l u tr b n ghi ch a trong b MIDlet c a chúng. Do đó, MIDlet 1 và MIDletấ ữ ệ ư ữ ả ứ ộ ủ
2 có th truy xu t d li u trong Record Store 1 và Record Store 2 nh ng chúng không th truyể ấ ữ ệ ư ể
xu t d li u trong Record Store3. Ng c l i, MIDlet 3 ch có th truy xu t d li u trongấ ữ ệ ượ ạ ỉ ể ấ ữ ệ
Record Store 3 và không th truy xu t d li u d li u trong Record Store 1 và Record Store 2.ể ấ ữ ệ ữ ệ
Tên c a các l u tr b n ghi ph i là duy nh t trong m t b MIDlet nh ng các b khác nhau cóủ ư ữ ả ả ấ ộ ộ ư ộ
th dùng trùng tên.ể
S u t m : Võ Thành Luân – tihonphysics@yahoo.comư ầ

Page 21
Các b n ghi trong m t l u tr b n ghi đ c s p x p thành các m ng byte. Các m ng byteả ộ ư ữ ả ượ ắ ế ả ả
không có cùng chi u dài và m i m ng byte đ c gán m t s ID b n ghi.ề ỗ ả ượ ộ ố ả
Các b n ghi đ c đ nh danh b ng m t s ID b n ghi (record ID) duy nh t. Các s ID b n ghiả ượ ị ằ ộ ố ả ấ ố ả
đ c gán theo th t b t đ u t 1. Các s s không đ c dùng l i khi m t b n ghi b xóa doượ ứ ự ắ ầ ừ ố ẽ ượ ạ ộ ả ị
đó s t n t i các kho ng tr ng trong các ID b n ghi. Đ c t MIDP không đ nh nghĩa chuy nẽ ồ ạ ả ố ả ặ ả ị ệ
gì x y ra khi đ t đ n s ID b n ghi t i đa, đi u này ph thu c vào ng d ng.ả ạ ế ố ả ố ề ụ ộ ứ ụ
1.1 Đ nh d ng (Foị ạ rmat), Thêm (Add) và Xóa (Delete) các b n ghiả
Thêm b n ghi g m hai b c. B c đ u tiên là đ nh d ng b n ghi theo đ nh d ng yêu c u vàả ồ ướ ướ ầ ị ạ ả ị ạ ầ
b c ti p theo là thêm b n ghi đã đ nh d ng vào l u tr b n ghi. S tu n t hóaướ ế ả ị ạ ư ữ ả ự ầ ự
(serialization) d li u l u tr b n ghi không đ c h tr , do đó l p trình viên ph i đ nh đ nhữ ệ ư ữ ả ượ ỗ ợ ậ ả ị ị
d ng các m ng byte đ xây d ng d li u l u tr b n ghiạ ả ể ự ữ ệ ư ữ ả
Sau đây là ví d c a vi c đ nh d ng d li u b n ghi, m m t l u tr b n ghi và sau đó thêmụ ủ ệ ị ạ ữ ệ ả ở ộ ư ữ ả
d li u b n ghi vào l u tr b n ghiữ ệ ả ư ữ ả
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream outputStream = new DataOutputStream(baos);
outputStream.writeByte(‘T’); // byte [0] Th ch lo i b n ghiẻ ỉ ạ ả
outputStream.writeInt(score); // byte [1] đ n [4]ế
outputStream.writeUTF(name); // byte [5] đ n 2 + name.lengthế
byte[] theRecord = boas.toByteArray();
recordStore rs = null;
rs = RecordStore.openRecordStore(“RecordStoreName”, CreateIfNoExist);
int RecordID = rs.addRecord(theRecord, 0, theRecord.length);
Hình 2. Thêm b n ghiả
1.1.a Đ nh d ng d li u b n ghiị ạ ữ ệ ả
Trong ví d trên, hai dòng đ u t o m t lu ng xu t đ gi d li u b n ghi. S d ng đ iụ ầ ạ ộ ồ ấ ể ữ ữ ệ ả ử ụ ố
t ng DataOutputStream (b c m ng byte) cho phép các b n ghi d dàng đ c đ nh d ng theoượ ọ ả ả ễ ượ ị ạ
các ki u chu n c a Java (long, int, string,…) mà không ph i quan tâm đ n tách nó thành dể ẩ ủ ả ế ữ
li u byte. Ph ng th c writeByte(), writeInt(), và writeUTF() đ nh d ng d li u nh trongệ ươ ứ ị ạ ữ ệ ư
hình (tag, score, name). S d ng th (tag) làm byte đ u tiên có ích đ xác đ nh lo i b n ghi sauử ụ ẻ ầ ể ị ạ ả
này. Ph ng th c toByteArray() chép d li u trong lu ng xu t thành m t m ng byte ch a b nươ ứ ữ ệ ồ ấ ộ ả ứ ả
ghi đ l u tr . Bi n theRecord là tham chi u đ n d li u đã đ nh d ng.ể ư ữ ế ế ế ữ ệ ị ạ
1.1.b Thêm d b n ghi đã đ nh d ng vào l u tr b n ghiữ ả ị ạ ư ữ ả
Khi d li u đã đ c đ nh d ng, nó có th đ c thêm vào l u tr b n ghi. Phát bi uữ ệ ượ ị ạ ể ượ ư ữ ả ể
S u t m : Võ Thành Luân – tihonphysics@yahoo.comư ầ

Page 21
openRecordStore() t o và m m t l u tr b n ghi v i tên là RecordStoreName. Phát bi uạ ở ộ ư ữ ả ớ ể
addRecord() thêm b n khi (b t đ u b ng byte 0 c a theRecord) và tr v ID b n ghi g n v iả ắ ầ ằ ủ ả ề ả ắ ớ
record này.
1.1.c Xóa b n ghiả
B n ghi đ c xóa b ng cách chuy n s ID b n ghi cho ph ng th c deleteRecord() c a đ iả ượ ằ ể ố ả ươ ứ ủ ố
t ng RecordStore.ượ
Ví d , b n ghi 7 b xóa b ng ph ng th c deleteRecord(), n u m t b n ghi khác đ c thêmụ ả ị ằ ươ ứ ế ộ ả ượ
vào thì s ID b n ghi s là 8 và ID b n ghi 7 s không đ c dùng l i.ố ả ẽ ả ẽ ượ ạ
1.2 L c các b n ghi (Filtering Records)ọ ả
Giao di n RecordFilter cung c p m t cách thu n ti n đ l c các b n ghi theo tiêu chu n c aệ ấ ộ ậ ệ ể ọ ả ẩ ủ
l p trình viên. RecordEnumeration có th đ c dùng đ duy t qua các b n ghi và ch tr vậ ể ượ ể ệ ả ỉ ả ề
các record phù h p v i tiêu chu n xác đ nh. Giao di n RecordFilter có ph ng th c matches()ợ ớ ẩ ị ệ ươ ứ
dùng đ xác đ nh tiêu chu n phù h p. Ph ng th c matches() có m t tham s đ u vào làể ị ẩ ợ ươ ứ ộ ố ầ
m ng byte bi u di n m t b n ghi. Ph ng th c ph i tr v true n u b n ghi này phù h p v iả ể ễ ộ ả ươ ứ ả ả ề ế ả ợ ớ
tiêu chu n đã đ nh nghĩa.ẩ ị
Hình 3 minh h a ví d cách s d ng giao di n RecordFilterọ ụ ử ụ ệ
Hình 3. L c b n ghiọ ả
class IntegerFilter implements RecordFilter {
public boolean matches(byte[] candidate) throws IlleegalArgumentException {
return(candidate[0] == ‘T’);
}
Trong ví d trên, l p IntegerFilter đ c dùng đ l c ra t t c các b n ghi có ‘T’ byte đ uụ ớ ượ ể ọ ấ ả ả ở ầ
tiên. Nh r ng các b n ghi không ph i có cùng đ nh d ng. Do đó có byte đ u tiên làm th (tag)ớ ằ ả ả ị ạ ầ ẻ
r t có ích. Ph ng th c matches() ch tr v true n u byte đ u tiên là ‘T’.ấ ươ ứ ỉ ả ề ế ầ
1.3 S p x p các b n ghiắ ế ả
Các b n ghi trong m t l u tr b n ghi có th đ c s p x p theo th t do l p trình viên đ nhả ộ ư ữ ả ể ượ ắ ế ứ ự ậ ị
nghĩa. Vi c s p x p đ c th c hi n thông qua giao di n RecordComparator. Duy t kê qua cácệ ắ ế ượ ự ệ ệ ệ
b n ghi s tr v các b n ghi theo th t s p x p đã đ nh nghĩa. Giao di n RecordComparatorả ẽ ả ề ả ứ ự ắ ế ị ệ
có ph ng th c compare() ph i đ c implement đ đ nh nghĩa cách hai b n ghi so sánh theoươ ứ ả ượ ể ị ả
th t . Các tham s đ u vào là hai m ng byte bi u di n hai b n ghi. Ph ng th c compare()ứ ự ố ầ ả ể ễ ả ươ ứ
ph i tr v m t trong ba giá tr :ả ả ề ộ ị
S u t m : Võ Thành Luân – tihonphysics@yahoo.comư ầ

Page 21
EQUIVALENT: Hai b n khi đ c xem là gi ng nhauả ượ ố
FOLLOWS: B n ghi đ u tiên có th t theo sau b n khi th hai.ả ầ ứ ự ả ứ
PRECEDES: B n ghi đ u tiên có th t đ ng tr c b n ghi th hai.ả ầ ứ ự ứ ướ ả ứ
Ví d s p x p các b n ghi s d ng giao di n RecordComparatorụ ắ ế ả ử ụ ệ
class IntegerCompare implements RecordComparator {
public int compare(byte[] b1, byte[] b2) {
DataInputStream is1 = new DataInputStream(new ByteArrayInputStream(b1));
DataInputStream is2 = new DataInputStream(new ByteArrayInputStream(b2));
is1.skip(1);
is2.skip(2);
int i1 = is1.readInt();
int i2 = is2.readInt();
if (i1 > i2) return RecordComparator.FOLLOWS;
if (i1 < i2) return RecordComparator.PRECEDES;
return RecordComparator.EQUIVALENT;
}
}
Trong ví d trên, các b n ghi đ c s p x p d a trên giá tr s nguyên ch a trong 4 byte sauụ ả ượ ắ ế ự ị ố ứ
byte th đ u tiên. Tham s b1 và b2 bi u di n hai b n ghi đ c chuy n cho ph ng th cẻ ầ ố ể ễ ả ượ ể ươ ứ
compare(). S d ng ph ng th c DataInputStream() cho phép s d ng các ki u d li u chínhử ụ ươ ứ ử ụ ể ữ ệ
c a Java (int, long, String) thay vì ph i thao tác tr c ti p v i d li u byte. Ph ng th c skip()ủ ả ự ế ớ ữ ệ ươ ứ
b qua byte th đ u tiên trong m i lu ng. Ph ng th c readInt() đ c s nguyên tr c ti p tỏ ẻ ầ ỗ ồ ươ ứ ọ ố ự ế ừ
lu ng nh p. Dòng cu i cùng so sánh các s nguyên và tr v giá tr (FOLLOWS, PRECEDES,ồ ậ ố ố ả ề ị
và EQUIVALENT). Nh v y th t s p x p c a toàn b b n ghi s đ c xác đ nh b i giá trư ậ ứ ự ắ ế ủ ộ ả ẽ ượ ị ở ị
c a các s nguyên.ủ ố
1.4 Li t kê (Enumerate) các b n ghiệ ả
Li t kê qua các b n ghi trong l u tr b n ghi đ c th c hi n b ng cách dùng giao di nệ ả ư ữ ả ượ ự ệ ằ ệ
RecordEnumeration k t h p v i các l p RecordFilter và RecordComparator. L pế ợ ớ ớ ớ
RecordEnumerator gi th t lu n lý c a các b n ghi. L p RecordFilter đ nh nghĩa t p conữ ứ ự ậ ủ ả ớ ị ậ
c a các b n ghi t l u tr b n ghi s đ c s p x p. RecordComparator đ nh nghĩa th t s pủ ả ừ ư ữ ả ẽ ượ ắ ế ị ứ ự ắ
x p c a các b n ghi. N u RecordFilter không đ c dùng thì t t c các b n ghi trong l u trế ủ ả ế ượ ấ ả ả ư ữ
b n ghi s đ c dùng. N u RecordComparator không đ c dùng thì các b n ghi s đ c trả ẽ ượ ế ượ ả ẽ ượ ả
v theo th t ng u nhiên.ề ứ ự ẫ
B li t kê có th đ c thi t l p c p nh t khi các b n ghi thay đ i ho c nó có th đ c thi tộ ệ ể ượ ế ậ ậ ậ ả ổ ặ ể ượ ế
l p b qua các thay đ i và đ c c p nh t th công sau. N u s li t kê đ c c p nh t tậ ỏ ổ ượ ậ ậ ủ ế ự ệ ượ ậ ậ ự
đ ng m i khi thêm ho c xóa b n ghi, thì nó có th làm ch m hi u su t c a ng d ng. Tuyộ ỗ ặ ả ể ậ ệ ấ ủ ứ ụ
nhiên, n u các b n ghi b xóa thì b li t kê có th tr v các b n ghi không h p l n u nóế ả ị ộ ệ ể ả ề ả ợ ệ ế
ch a đ c c p nh t. Gi i pháp là đ t c các b n ghi đang đ c thay đ i và sau đó g iư ượ ậ ậ ả ặ ờ ả ượ ổ ọ
ph ng th c rebuilt() đ xây d ng l i b li t kê m t cách th công.ươ ứ ể ự ạ ộ ệ ộ ủ
S u t m : Võ Thành Luân – tihonphysics@yahoo.comư ầ

Page 21
Các b n ghi duy t b ng cách dùng ph ng th c nextRecord(). L n đ u tiên đ c g i nó sả ệ ằ ươ ứ ầ ầ ượ ọ ẽ
tr v b n ghi đ u tiên trong t p li t kê. L n g i k ti p nó s tr v b n ghi k ti p theoả ề ả ầ ậ ệ ầ ọ ế ế ẽ ả ề ả ế ế
th t s p x p lu n lý.ứ ự ắ ế ậ
Ví d bi u di n quá trình li t kê b n ghiụ ể ễ ệ ả
IntegerFilter iFilt = new IntegerFilter();
IntegerCompare iCompare = new IntegerCompare();
RecordEnumeration intRecEnum = null;
intRecEnum = recordStore.enumerateRecords((RecordFilter)iFilt,
(RecordComparator)iCompare, false);
while (intRecEnum.hasNextElement()) {
byte b[] = intRecEnum.nextRecord();
}
// intRecEnum = recordStore(null, null, false);
Trong ví d trên, m t đ i t ng IntegerFilter và IntegerCompare đ c t o ra. IntegerFilter sụ ộ ố ượ ượ ạ ẽ
ch tr v các b n ghi ch a tr ng s nguyên. IntegerCompare s s p x p các b n ghi theoỉ ả ề ả ứ ườ ố ẽ ắ ế ả
th t s h c.ứ ự ố ọ
B li t kê b n ghi đ c đ nh nghĩa và đ c kh i t o b ng output c a ph ng th cộ ệ ả ượ ị ượ ở ạ ằ ủ ươ ứ
enumerateRecords() c a l p RecordStore.ủ ớ
Ph ng th c enumerateRecords() có ba tham s . Tham s đ u tiên là tham chi u đ i t ngươ ứ ố ố ầ ế ố ượ
l c (iFilt). Tham s th hai là tham chi u đ n đ i t ng s p x p (iCompare). Tham s cu iọ ố ứ ế ế ố ượ ắ ế ố ố
cùng là m t giá tr boolean xác đ nh b li t kê có đ c c p nh t khi các b n ghi thay đ i,ộ ị ị ộ ệ ượ ậ ậ ả ổ
thêm, xóa hay không.
Vòng l p while() ch cách duy t các b n ghi theo th t yêu c u. Vòng l p while() s ti p t cặ ỉ ệ ả ứ ự ầ ặ ẽ ế ụ
mi n là b li t kê còn ch a m t b n ghi.ễ ộ ệ ứ ộ ả
Dòng cu i cùng bi u di n ví d cách duy t t t c b n ghi theo th t ng u nhiên. Nh taố ể ễ ụ ệ ấ ả ả ứ ự ẫ ư
th y, các hai tham s l c và so sánh đ u đ c đ t là null.ấ ố ọ ề ượ ặ
S u t m : Võ Thành Luân – tihonphysics@yahoo.comư ầ

