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

📄 recordstore.java

📁 有关j2me的很好的例子可以研究一下
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	    RecordHeader newrh = null;	    	    try {		rh = findRecord(recordId, false); // throws InvalidRIDException	    } catch (java.io.IOException ioe) {		throw new RecordStoreException("error finding record data");	    }	    /*	     * The size of the data and space allocated to the	     * current record is known here, as is the new size.	     * Determine if the new data will fit, or if this 	     * record will have to be stored elsewhere.	     */	    if (numBytes <= rh.blockSize - DB_RECORD_HEADER_LENGTH) {		/*		 * The new data should fit within the existing record		 * location in the file. Store the new data and		 * patch up the record's header fields.		 */		int allocSize = getAllocSize(numBytes);		if (rh.blockSize - allocSize >= 		    DB_BLOCK_SIZE + DB_RECORD_HEADER_LENGTH) {		    splitRecord(rh, allocSize); // sets rh.blockSize	        }		rh.dataLenOrNextFree = numBytes;				try {		    rh.store(); // write the new record header		    recHeadCache.insert(rh);  // add to cache				    if (newData != null) {			rh.write(newData, offset);		    }		} catch (java.io.IOException ioe) {		    throw new RecordStoreException("error writing record" +						   " data");		}	    } else {		/*		 * The new data is longer than the old data.  It needs to		 * be relocated to elsewhere within <code>dbfile</code>. 		 * Search the free list to see if there's a space where to		 * store it.  Otherwise append it to the end of the file.		 */		freeRecord(rh); // calls rh.store()		newrh = allocateNewRecordStorage(recordId, numBytes);		try {		    if (newData != null) {			newrh.write(newData, offset);			// NOTE: I/O exception leaves space allocated & unused		    }		} catch (java.io.IOException ioe) {		    throw new RecordStoreException("error moving record " +						   "data");		}	    }	    	    // update database header info and sync to file	    dbVersion++;	    storeDBState();	    notifyRecordChangedListeners(recordId);	}    }    /*     * Public RecordStore accessor methods     */    /**     * Returns the name of this RecordStore. Not synchronized as     * the name is immutable.     *      * @return the name of this RecordStore.      *      * @exception RecordStoreNotOpenException if the record store is closed      */     public String getName() 	throws RecordStoreNotOpenException     {	checkOpen();	return recordStoreName;    }    /**     * Each time a record store is modified (record added, modified, deleted),      * it's <em>version</em> is incremented. This can be used by MIDlets to      * quickly tell if anything has been modified.      *     * The initial version number is implementation dependent.     * The increment is a positive integer greater than 0.     * The version number only increases as the RecordStore is updated.     *     * @return the current record store version.      *      * @exception RecordStoreNotOpenException if the record store is not open.      */     public int getVersion() 	throws RecordStoreNotOpenException     {	checkOpen();	return dbVersion;    }    /**     * Returns the number of records currently in the record store.      *     * @return the number of records currently in the record store.      *      * @exception RecordStoreNotOpenException if the record store is not open.      */     public int getNumRecords() 	throws RecordStoreNotOpenException     {	checkOpen();	return dbNumLiveRecords;    }        /**     * Returns the amount of space, in bytes, that the record store     * occupies. The size returned includes any overhead associated     * with the implementation, such as the data structures     * used to hold the state of the record store, etc.     *     * @exception RecordStoreNotOpenException if the record store is      *            not open.      *      * @return the size of the record store in bytes.     */     public int getSize() 	throws RecordStoreNotOpenException     {	checkOpen();	// return the file size of the record store file	return dbDataEnd;    }    /**     * Returns the amount of additional room (in bytes) available for      * this record store to grow. Note that this is not necessarily     * the amount of extra MIDlet-level data which can be stored,     * as implementations may store additional data structures with     * each record to support integration with native applications,     * synchronization, etc.     *      * @exception RecordStoreNotOpenException if the record store is not open.      *      * @return the amount of additional room (in bytes) available for      *         this record store to grow.      */     public int getSizeAvailable() 	throws RecordStoreNotOpenException     {	checkOpen();	int rv = RecordStoreFile.spaceAvailable() - 	    DB_BLOCK_SIZE - DB_RECORD_HEADER_LENGTH;	return (rv < 0) ? 0 : rv;    }        /**     * Returns the last time the record store was modified, in the format      * used by System.currentTimeMillis().      *      * @return the last time the record store was modified, in the format      *         used by <code>System.currentTimeMillis()</code>.      *      * @exception RecordStoreNotOpenException if the record store is not open.      */     public long getLastModified() 	throws RecordStoreNotOpenException     {	checkOpen();	return dbLastModified;    }    /**     * Adds the specified RecordListener. If the specified listener      * is already registered, it will not be added a second time.      * When a record store is closed, all listeners are removed.      *      * @param listener the RecordChangedListener to add.      *     * @see #removeRecordListener     */     public void addRecordListener(RecordListener listener)     {	synchronized (rsLock) {	    if (!recordListener.contains(listener))		recordListener.addElement(listener);	}    }    /**     * Removes the specified RecordListener. If the specified listener      * is not registered, this method does nothing.      *      * @param listener the RecordChangedListener to remove.      *     * @see #addRecordListener     */     public void removeRecordListener(RecordListener listener)     {	synchronized (rsLock) {	    recordListener.removeElement(listener);	}    }        /**     * Returns the recordId of the next record to be added to the      * record store. This can be useful for setting up pseudo-relational      * relationships. That is, if you have two or more      * record stores whose records need to refer to one another, you can      * predetermine the recordIds of the records that will be created      * in one record store, before populating the fields and allocating      * the record in another record store. Note that the recordId returned      * is only valid while the record store remains open and until a call      * to <code>addRecord()</code>.       *      * @return the record id of the next record to be added to the      *         record store.      *      * @exception RecordStoreNotOpenException if the record store is not open.      * @exception RecordStoreException if a different record store-related      *            exception occurred.      */     public int getNextRecordID() 	throws RecordStoreNotOpenException, RecordStoreException     {	checkOpen();	return dbNextRecordID;    }        /**     * Returns an enumeration for traversing a set of records in the      * record store in an optionally specified order.<p>      *      * The filter, if non-null, will be used to determine what      * subset of the record store records will be used.<p>      *      * The comparator, if non-null, will be used to determine the      * order in which the records are returned.<p>      *      * If both the filter and comparator are 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.<p>     *      * The first call to <code>RecordEnumeration.nextRecord()</code>      * returns the record data from the first record in the sequence.     * Subsequent calls to <code>RecordEnumeration.nextRecord()</code>     * return the next consecutive record's data. To return the record     * data from the previous consecutive from any      * given point in the enumeration, call <code>previousRecord()</code>.      * On the other hand, if after creation the first call is to      * <code>previousRecord()</code>, the record data of the last element     * of the enumeration will be returned. Each subsequent call to      * <code>previousRecord()</code> will step backwards through the     * sequence.      *     * @param filter if non-null, will be used to determine what      *        subset of the record store records will be used.      * @param comparator if non-null, will be used to determine the      *        order in which the records are returned.      * @param keepUpdated if true, the enumerator will keep its enumeration      *        current with any changes in the records of the record store.      *        Use with caution as there are possible performance      *        consequences. If false the enumeration will not be kept      *        current and may return recordIds for records that have been     *        deleted or miss records that are added later. It may also      *        return records out of order that have been  modified after the     *        enumeration was built. Note that any changes to records in the     *        record store are accurately reflected when the record is later     *        retrieved, either directly or through the enumeration. The      *        thing that is risked by setting this parameter false is the      *        filtering and sorting order of the enumeration when records      *        are modified, added, or deleted.     *      * @exception RecordStoreNotOpenException if the record store is not open.      *     * @see RecordEnumeration#rebuild     *      * @return an enumeration for traversing a set of records in the      *         record store in an optionally specified order.     */     public RecordEnumeration enumerateRecords(RecordFilter filter, 					      RecordComparator comparator, 					      boolean keepUpdated) 	throws RecordStoreNotOpenException     {	checkOpen();	return new RecordEnumerationImpl(this, filter, 					 comparator, keepUpdated);    }    /*     * Private Memory Management Methods     */    /**     * Find the record header for a record <code>recordId</code>.     *     * @param recordId the id of the desired record header.     * @param addToCache true if this record should be added to cache      *        if found.     *     * @return the record header for the given record, or null if      *         the record cannot be found.     */    private RecordHeader findRecord(int recordId, boolean addToCache)	throws InvalidRecordIDException, java.io.IOException    {	RecordHeader rh;	int offset;		int cur_offset = dbFirstRecordOffset;	// if no records exist, throw an exception	if (cur_offset == 0) {	    throw new InvalidRecordIDException();	}		// look for the record in the cache	rh = recHeadCache.get(recordId);	if (rh != null) {	    return rh;	}		/*	 * requested record header is NOT in cache...	 * search through the linked list of records	 * in the file. 	 */	rh = new RecordHeader();		while (cur_offset != 0) {	    rh.load(cur_offset);	    if (rh.id == recordId) {		break;	    } else {		cur_offset = rh.nextOffset;	    }	} 		if (cur_offset == 0) { 	    // hit the end of the linked list w/o finding record.	    throw new InvalidRecordIDException();	}		if (addToCache)	    recHeadCache.insert(rh);	return rh;    }        /**     * Return the block allocation size for a record with <code>numBytes     * </code> data bytes.  This includes space for the record header     * and is a multiple of <code>DB_BLOCK_SIZE</code>.     *     * @param numBytes number of data bytes that will be stored in record     *     * @return the amount of space to allocate for this record.     */    private int getAllocSize(int numBytes) {	int rv;	int pad;	rv = DB_RECORD_HEADER_LENGTH + numBytes;	pad = DB_BLOCK_SIZE - (rv % DB_BLOCK_SIZE);	if (pad != DB_BLOCK_SIZE)	    rv += pad;	return rv;    }    /**     * Returns a new record header for record <code>id</code> large     * enough to hold <code>dataSize</code> bytes of record data.     *     * Picks a free block using a first fit strategy that is      * large enough for a record header and the associated     * record data.  The block will be a multiple of DB_BLOCK_SIZE.     *     * @param id the record id to assign to the returned record header.     * @param dataSize length of record data that will be      *        stored with this record.

⌨️ 快捷键说明

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