Ộ Ộ
Ậ Ậ
Ế Ế
Ị Ị
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 nonvolatile 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 ế ị ư ạ ổ ệ ư (nonvolatile 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()); } }