⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 feb02_ericg.txt

📁 TechTips j2me的常用技巧. 网络功能
💻 TXT
📖 第 1 页 / 共 2 页
字号:
    }

    public Employee( int employeeID, String firstName,
                     String lastName, int managerID ){
        this.employeeID = employeeID;t
        this.firstName = firstName;
        this.lastName = lastName;
        this.managerID = managerID;
    }

    public int getID() { return employeeID; }

    public String getFirstName() {
        return firstName != null ? firstName : ""; 
    }

    public String getLastName() {
        return lastName != null ? lastName : "";
    }

    public int getManagerID() { return managerID; }

    public String toString() {
        StringBuffer b = new StringBuffer();
        b.append( '{' );
        b.append( employeeID );
        b.append( ',' );
        b.append( firstName );
        b.append( ',' );
        b.append( lastName );
        b.append( ',' );
        b.append( managerID );
        b.append( '}' );
        return b.toString();
    }

    public byte[] persist() throws IOException {
        ByteArrayOutputStream bout = 
                           new ByteArrayOutputStream();
        DataOutputStream      dout = 
                          new DataOutputStream( bout );

        dout.writeInt( getID() );
        dout.writeUTF( getFirstName() );
        dout.writeUTF( getLastName() );
        dout.writeInt( getManagerID() );
        dout.flush();

        return bout.toByteArray();
    }

    public void resurrect( byte[] data ) 
                                   throws IOException {
        ByteArrayInputStream bin = 
                      new ByteArrayInputStream( data );
        DataInputStream      din = 
                            new DataInputStream( bin );

        employeeID = din.readInt();
        firstName = din.readUTF();
        lastName = din.readUTF();
        managerID = din.readInt();
    }
}

The persistence is actually accomplished using the
DataOutputStream and DataInputStream classes, which allow you to 
easily write and read Java primitives and strings. With the
Employee class, then, an employee can be persisted at any point, 
like this:

    Employee emp = .....; // an employee instance

    try {
        byte[] persisted = emp.persist();
    }
    catch( java.io.IOException e ){
        // do something here
    }
        
Restoring the employee is done like this:

    byte[] persisted = ....; // presistence info
    Employee emp = new Employee();
    
    try {
        emp.resurrect( persisted );
    }
    catch( java.io.IOException e ){
        // do something here
    }
    
Note that the Persistent interface uses byte arrays, not byte 
streams, for storing the persistence information. This is a 
deliberate choice. In MIDP applications you're most likely to 
persist objects to the RMS, and the RMS APIs are array-based, not
stream-based. That said, it would be just as simple to write 
stream-based persistence methods.

Things are more complicated, of course, if your objects contain 
references to other persistent objects. The example above
avoids this issue by storing the manager ID in the Employee
class. A more natural implementation is to use a reference to 
another Employee object. This complicates the persistence.
That's because, instead of persisting a single object, you need 
to persist a sequence of objects, possibly with cross-references 
to each other. Writing the code to deal with this scenario is 
non-trivial. You need to traverse the object graph, ensure that
each object gets written at most once, and deal with cycles in 
the graph. It's better to avoid these issues by making persisted 
objects completely self-contained, and use keys (unique 
identifiers) to link objects together.

Classes that don't implement the Persistent interface can also be 
persisted, but only if they expose enough information in their 
public interface. The java.util.Vector class, for example, can be 
persisted using static methods defined on a helper class:

import java.io.*;
import java.util.*;

public class VectorHelper {

    private static final int NULL = 0;
    private static final int INTEGER = 1;
    private static final int STRING = 2;
    private static final int PERSISTENT = 3;

    public static byte[] persist( Vector v )
                            throws IOException {
        ByteArrayOutputStream bout =
                          new ByteArrayOutputStream();
        DataOutputStream      dout =
                          new DataOutputStream( bout );

        int n = v.size();
        dout.writeInt( n );

        for( int i = 0; i < n; ++i ){
          Object o = v.elementAt( i );
            if( o instanceof String ){
                dout.writeByte( STRING );
                dout.writeUTF( (String) o );
            } else if( o instanceof Integer ){
                dout.writeByte( INTEGER );
                dout.writeInt( 
                            ((Integer) o).intValue() );
            } else if( o instanceof Persistent ){
                dout.writeByte( PERSISTENT );
                dout.writeUTF( 
                              o.getClass().getName() );
                byte[] data = 
                            ((Persistent) o).persist();
                dout.writeInt( data.length );
                if( data.length > 0 ){
                   dout.write( data );
                }
            } else if( o == null ){
                dout.writeByte( NULL );
            } else {
                throw new IOException( 
                "Cannot persist " +"object of type " +
                   o.getClass().getName() );
            }
        }

        dout.flush();

        return bout.toByteArray();
    }

    public static Vector resurrect( byte[] persisted )
                            throws IOException {
        ByteArrayInputStream bin =
                    new ByteArrayInputStream( 
                                          persisted );
        DataInputStream      din =
                    new DataInputStream( bin );

        Vector v = new Vector();
        int n = din.readInt();

        for( int i = 0; i < n; ++i ){
            int type = din.readByte();
            if( type == NULL ){
                v.addElement( null );
            } else if( type == INTEGER ){
                v.addElement( new
                       Integer( din.readInt() ) );
            } else if( type == STRING ){
                v.addElement( din.readUTF() );
            } else if( type == PERSISTENT ){
                String cname = din.readUTF();
                int    len = din.readInt();
                byte[] tmp = new byte[ len ];

                din.readFully( tmp );

                try {
                    Class cl = Class.forName( cname );
                    Object o = cl.newInstance();
                    ((Persistent) o).resurrect( tmp );
                    v.addElement( o );
                }
                catch( IOException e ){
                    throw e;
                }
                catch( Exception e ){
                    throw new IOException( 
                         "Exception " +e.toString() );
                }
                } else {
                   throw new IOException( "Unknown " +
                   "type " + type );
            }
        }

        return v;
  
    }
}

For brevity, the helper class only handles vectors whose 
elements are of type Integer or String, or that implement the 
Persistent interface. It can be easily extended to support other 
core types such as Long and Boolean.

Note that the VectorHelper class is fairly generic. So it has to 
write type information as part of the persistence  data in order 
to correctly recreate the vector's contents. Most vectors 
typically hold elements of the same type. In that case you might
be better off treating the vector as an array of objects, and 
simply writing out the element count and then each element, 
without all the extra type information.

Here is a simple MIDlet that uses the classes introduced in this 
tip to persist information to an RMS record store. The first time 
you run the MIDlet, it saves objects into the record store. The 
next run of the MIDlet reads the objects and displays their 
values.

import java.io.*;
import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

public class PersistenceTest extends MIDlet
                 implements CommandListener {

    private Display   display;
    private Form      mainForm;

    public static final Command exitCommand =
                         new Command( "Exit",
                                     Command.EXIT, 1 ); 

    public PersistenceTest(){
    }

    public void commandAction( Command c,
                               Displayable d ){
        if( c == exitCommand ){
            exitMIDlet();
        }
    }

    protected void destroyApp( boolean unconditional )
                    throws MIDletStateChangeException {
        exitMIDlet();
    }

    public void exitMIDlet(){
        notifyDestroyed();
    }

    public Display getDisplay(){ return display; }

    protected void initMIDlet(){
        String str;
        RecordStore rs = null;

        try {
            rs =
                RecordStore.openRecordStore( 
                                       "test2", true );

            if( rs.getNumRecords() == 0 ){
                str = store( rs );
            } else {
                str = retrieve( rs );
            }
        }
        catch( Exception e ){
            str = e.toString();
        }

        mainForm = new Form( "MainForm" );
        mainForm.addCommand( exitCommand );
        mainForm.setCommandListener( this );
        mainForm.append( str );

        getDisplay().setCurrent( mainForm );
        
        if( rs != null ){
            try {
                rs.closeRecordStore();
            }
            catch( RecordStoreException e ){
            }
        }
    }

    protected void pauseApp(){
    }

    protected void startApp()
                    throws MIDletStateChangeException {
        if( display == null ){ 
            display = Display.getDisplay( this );
            initMIDlet();
        }
    }

    private String store( RecordStore rs )
                           throws RecordStoreException,
                                  IOException {
        Employee emp = new Employee( 
                                1, "Joe", "Clark", 0 );
        byte[]   data = emp.persist();

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

        Vector v = new Vector();
        v.addElement( new Integer( 99 ) );
        v.addElement( "The Great One" );
        v.addElement( new Employee( 99, "Wayne",
                                    "Gretzky", 1 ) );

        data = VectorHelper.persist( v );
        rs.addRecord( data, 0, data.length );

        return "Wrote " + emp.toString() + " and " +
               v.toString();
    }

    private String retrieve( RecordStore rs )
                           throws RecordStoreException,
                                  IOException {

        byte[]   data = rs.getRecord( 1 );
        Employee emp = new Employee();

        emp.resurrect( data );

        data = rs.getRecord( 2 );
        Vector v = VectorHelper.resurrect( data );

        return "Read " + emp.toString() + " and " +
               v.toString();
    }
}

.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

IMPORTANT: Please read our Terms of Use, Privacy, and Licensing
policies:
http://www.sun.com/share/text/termsofuse.html
http://www.sun.com/privacy/ 
http://developer.java.sun.com/berkeley_license.html

* FEEDBACK
  Comments? Send your feedback on the J2ME Tech Tips to: 
  
  jdc-webmaster@sun.com

* SUBSCRIBE/UNSUBSCRIBE
  - To subscribe, go to the subscriptions page,
    (http://developer.java.sun.com/subscription/), choose
    the newsletters you want to subscribe to and click "Update".
  - To unsubscribe, go to the subscriptions page,
    (http://developer.java.sun.com/subscription/), uncheck the
    appropriate checkbox, and click "Update".
  - To use our one-click unsubscribe facility, see the link at 
    the end of this email:
    
- ARCHIVES
You'll find the J2ME Tech Tips archives at:

http://java.sun.com/jdc/J2METechTips/index.html


- COPYRIGHT
Copyright 2002 Sun Microsystems, Inc. All rights reserved.
901 San Antonio Road, Palo Alto, California 94303 USA.

This document is protected by copyright. For more information, see:

http://java.sun.com/jdc/copyright.html

J2ME Tech Tips 
February 26, 2002

Sun, Sun Microsystems, Java, Java Developer Connection, J2ME, and
J2SE, are trademarks or registered trademarks of Sun Microsystems, 
Inc. in the United States and other countries.




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -