在 j2me 和 NetBeans 中运行相同代码时获得不同的输出

Posted

技术标签:

【中文标题】在 j2me 和 NetBeans 中运行相同代码时获得不同的输出【英文标题】:Getting different output while running the same code in j2me & NetBeans 【发布时间】:2012-03-15 17:37:52 【问题描述】:

在 j2me 和 NetBeans 中运行以下代码:

此代码用于记录过滤(搜索记录)。

问题在于,当我们在 j2me 中运行这段代码时,它会从头开始搜索,而在 NetBeans 中则是反向搜索。

        import javax.microedition.rms.*;
        import javax.microedition.midlet.*;
        import javax.microedition.lcdui.*;
        import java.io.*;
        import javax.microedition.rms.RecordFilter;
        public class SearchExample extends MIDlet implements CommandListener
        
        private Display display;
        private Alert alert;
        private Form form;
        private Command exit;
        private Command start;
        private RecordStore recordstore = null;
        private RecordEnumeration recordEnumeration = null;
        private Filter filter = null;
        public SearchExample ()
        
        display = Display.getDisplay(this);
        exit = new Command("Exit", Command.SCREEN, 1);
        start = new Command("Start", Command.SCREEN, 1);
        form = new Form("Mixed RecordEnumeration", null);
        form.addCommand(exit);
        form.addCommand(start);
        form.setCommandListener(this);
        
        public void startApp()
        
        display.setCurrent(form);
        
        public void pauseApp()
        
        
        public void destroyApp( boolean unconditional )
        
        
        public void commandAction(Command command, Displayable displayable)
        
        if (command == exit)
        
        destroyApp(true);
        notifyDestroyed();
        
        else if (command == start)
        
        try
        
        recordstore = RecordStore.openRecordStore("myRecordStore", true );
        
        catch (Exception error)
        
        alert = new Alert("Error Creating",error.toString(), null, AlertType.WARNING);
        alert.setTimeout(Alert.FOREVER);
        display.setCurrent(alert);
        
        try
        
        String outputData[] = "Mary", "Adam","dancebob","bobby","bob1";
        for (int x = 0 ; x < outputData.length; x++)
        

        byte[] byteOutputData = outputData[x].getBytes();
        recordstore.addRecord(byteOutputData, 0,byteOutputData.length);
        
        
        catch ( Exception error)
        
        alert = new Alert("Error Writing",error.toString(), null, AlertType.WARNING);
        alert.setTimeout(Alert.FOREVER);
        display.setCurrent(alert);
        
        try
        
        filter = new Filter("Bob");
        StringBuffer sbuf=new StringBuffer();
        recordEnumeration = recordstore.enumerateRecords(filter, null, false);
        if (recordEnumeration.numRecords() > 0)
        
        for(int i=0;i<recordEnumeration.numRecords();i++)
        String string = new String(recordEnumeration.nextRecord());
        sbuf.append(string+"\n");
        

        alert = new Alert("Reading", sbuf.toString(),null, AlertType.WARNING);
        alert.setTimeout(Alert.FOREVER);
        display.setCurrent(alert);
        
        
        catch (Exception error)
        
        alert = new Alert("Error Reading",error.toString(), null, AlertType.WARNING);
        alert.setTimeout(Alert.FOREVER);
        display.setCurrent(alert);
        
        try
        
        recordstore.closeRecordStore();
        
        catch (Exception error)
        
        alert = new Alert("Error Closing",error.toString(), null, AlertType.WARNING);
        alert.setTimeout(Alert.FOREVER);
        display.setCurrent(alert);
        
        if (RecordStore.listRecordStores() != null)
        
        try
        
        RecordStore.deleteRecordStore("myRecordStore");
        recordEnumeration.destroy();
        filter.filterClose();
        
        catch (Exception error)
        
        alert = new Alert("Error Removing",error.toString(), null, AlertType.WARNING);
        alert.setTimeout(Alert.FOREVER);
        display.setCurrent(alert);
        
        

        
        
        
        class Filter implements RecordFilter
        
        private String search = null;
        private ByteArrayInputStream inputstream = null;
        private DataInputStream datainputstream = null;
        public Filter(String search)
        
        this.search = search.toLowerCase();
        
        public boolean matches(byte[] suspect)
        
        String string = new String(suspect).toLowerCase();

        if (string!= null && string.indexOf(search) != -1)
            return true;
        else
            return false;
        

        public void filterClose()
        
        try
        
        if (inputstream != null)
        
        inputstream.close();
        
        if (datainputstream != null)
        
        datainputstream.close();
        
        
        catch ( Exception error)
        
        
        
        

【问题讨论】:

【参考方案1】:

您的代码 sn-p 非常大并且格式不好,因此可能还有一些我没有注意到的其他错误,但如果您关心的是您在此行创建的遍历枚举的顺序:

recordEnumeration = recordstore.enumerateRecords(filter, null, false);

那么这是正常行为。 MIDP RMS API documentation 声明当第二个参数是 null(并且它在您的代码中)时,记录会以未定义的顺序遍历。

请看下方报价,关注RecordComparator comparator相关细节

public RecordEnumeration enumerateRecords(RecordFilter filter,
                                      RecordComparator comparator,
                                      boolean keepUpdated)
                               throws RecordStoreNotOpenException

Returns an enumeration for traversing a set of records in the record store
  in an optionally specified order.

The filter, if non-null, will be used to determine what subset
  of the record store records will be used.

The comparator, if non-null, will be used to determine the order
  in which the records are returned.

If both the filter and comparator is null, the enumeration will traverse
  all records in the record store in an undefined order. This is the most
  efficient way to traverse all of the records in a record store. If a filter
  is used with a null comparator, the enumeration will traverse the filtered
  records in an undefined order. The first call to RecordEnumeration.nextRecord()
  returns the record data from the first record in the sequence. Subsequent calls
  to RecordEnumeration.nextRecord() return the next consecutive record's data.
  To return the record data from the previous consecutive from any given point
  in the enumeration, call previousRecord(). On the other hand, if after creation
  the first call is to previousRecord(), the record data of the last element
  of the enumeration will be returned. Each subsequent call to previousRecord()
  will step backwards through the sequence.

Parameters:
    filter - if non-null, will be used to determine what subset of the
     record store records will be used
    comparator - if non-null, will be used to determine the order in which
     the records are returned
    ...

您可能会认为,每次运行 midlet 时,Netbeans 模拟器都会以相同的方式遍历记录,这只是一个幸运的巧合;理论上允许在每次运行时更改顺序。

【讨论】:

以上是关于在 j2me 和 NetBeans 中运行相同代码时获得不同的输出的主要内容,如果未能解决你的问题,请参考以下文章

Java ME (J2ME) 开发:NetBeans 与 Eclipse

在 J2ME 项目 (Netbeans 6.9.1) 中未检测到预处理器块

在 NetBeans 12.4 中安装 J2ME 插件

J2ME:预取错误 -5。媒体异常

J2ME 应用程序开发指南

如何使用j2me将数据保存在手机中?