使用Preferences API 參考資料
Preferences的誤解:
首先要指明的是:Preferences API并不是為訪問(wèn)Windows注冊(cè)表而設(shè)計(jì)的。
我們之所以會(huì)有上面的誤解是由于Sun的Windows版本的JDK在實(shí)現(xiàn)Preferences API時(shí)使用了Windows注冊(cè)表作為存儲(chǔ)庫(kù),即我們用Preferences API存儲(chǔ)的數(shù)據(jù)會(huì)保存到Windows注冊(cè)表中,這樣Preferenes API也就有了訪問(wèn)Windows注冊(cè)表的能力。但是換到其它的平臺(tái)或其它廠商的JDK實(shí)現(xiàn)又會(huì)怎么樣呢?這個(gè)問(wèn)題是和Preferences API的實(shí)現(xiàn)相關(guān)的,我們沒(méi)有辦法回答。
Preferences適用的條件:
如果程序不關(guān)心存儲(chǔ)庫(kù)的細(xì)節(jié),只是要找一個(gè)存放數(shù)據(jù)的地方,那么Preferences API很合適。
Preferences API的局限:
一個(gè)Java軟件,這次我在Sun的JDK上運(yùn)行并使用Preferences API保存了我的個(gè)人喜好,下次我在IBM的JDK上運(yùn)行,這時(shí)我的個(gè)人喜好還可以通過(guò)Preferences API得到嗎?可能可以也可能不可以,這時(shí)的行為是由Sun和IBM的Preferences API實(shí)現(xiàn)決定的。(在相同的JDK實(shí)現(xiàn)上可以使用Preferences API來(lái)在不同的程序間共享數(shù)據(jù))
一個(gè)Java軟件需要讓用戶設(shè)置是否和操作系統(tǒng)一起啟動(dòng),類似的需求還很多。這類需求就是要求Java程序有真正的和相關(guān)操作系統(tǒng)協(xié)同的能力。這種能力不是Preferences API的設(shè)計(jì)目標(biāo)。
使用JNI 參考資料
Windows操作系統(tǒng)提供了操作注冊(cè)表的API,因此用JNI將Java和這些API連接起來(lái)我們就獲得了用Java操作注冊(cè)表的能力。這說(shuō)起來(lái)有些簡(jiǎn)單,實(shí)現(xiàn)起來(lái)卻需要處理大量的細(xì)節(jié)。幸運(yùn)的是這樣的工作已經(jīng)有人做了,我們要感謝他們。下面我們就來(lái)看看其中的一個(gè)包。
com.ice.jni.registry包是通過(guò)JNI(Java native interface)實(shí)現(xiàn)的Windows注冊(cè)表操作API,可以用來(lái)訪問(wèn)、修改和導(dǎo)出Windows注冊(cè)表。現(xiàn)在這個(gè)包已經(jīng)公開了,可以放心的使用而不必?fù)?dān)心license的問(wèn)題,并且包括一個(gè)構(gòu)建好的DLL和Java、C的源代碼。它可以在Java 1.1和更高的版本上工作。
下面詳細(xì)的描述一下這個(gè)包中的類,數(shù)量不是很多:
- HexNumberFormat 用來(lái)格式化和分析十六進(jìn)制整數(shù)。
- RegBinaryValue 表示類型為REG_BINARY的注冊(cè)表值。REG_BINARY是指任意形式的二進(jìn)制數(shù)。
- RegDWordValue 表示類型為REG_DWORD的注冊(cè)表值。REG_DWORD是指一個(gè)32位的整數(shù)。根據(jù)該整數(shù)的字節(jié)序不同又分為REG_DWORD_LITTLE_ENDIAN和REG_DWORD_BIG_ENDIAN。在Windows中REG_DWORD和REG_DWORD_LITTLE_ENDIAN有相同的含義。
- RegistryValue 表示任意類型的注冊(cè)表值,這是一個(gè)抽象類,不能被實(shí)例化。
- RegMultiStringValue 表示類型為REG_MULTI_SZ的注冊(cè)表值。REG_MULTI_SZ是一個(gè)null-terminated的字符串的序列。
- RegStringValue 表示類型為REG_SZ和REG_EXPAND_SZ的注冊(cè)表值。REG_SZ是指一個(gè)null-terminated的字符串,REG_EXPAND_SZ是指一個(gè)含有未展開的環(huán)境變量的null-terminated的字符串。
- Registry 這個(gè)類定義了定級(jí)項(xiàng)(Key),包括HKEY_CLASSES_ROOT、HKEY_CURRENT_CONFIG、HKEY_CURRENT_USER、HKEY_DYN_DATA、HKEY_LOCAL_MACHINE、HKEY_PERFORMANCE_DATA和HKEY_USERS。還定義了錯(cuò)誤代碼,這些錯(cuò)誤代碼會(huì)包含在RegistryException中。最后是一些工具方法,如dumpHexData、exportRegistryKey、getErrorMessage、getTopLevelKey、openSubkey、parseArgumentString、parseArgumentVector、splitString和usage。
- RegistryKey 定義了注冊(cè)表的一個(gè)表項(xiàng)(Key)和相關(guān)的一些操作。
RegistryKey的方法概要:
方法 | 簡(jiǎn)短描述 |
void closeKey() | 關(guān)閉該subkey。 |
RegistryKey connectRegistry(java.lang.String hostName) | 連接遠(yuǎn)程主機(jī)hostName的注冊(cè)表。 |
RegistryKey createSubKey(java.lang.String subkey, java.lang.String className) | 創(chuàng)建和打開該key的subkey,具有寫權(quán)限。 |
RegistryKey createSubKey(java.lang.String subKey, java.lang.String className, int access) | 創(chuàng)建和打開該key的subkey,具有指定的權(quán)限。 |
int decrDoubleWord(java.lang.String valueName) | 該方法將消減REG_DWORD的值。 |
void deleteSubKey(java.lang.String subKey) | 刪除該subkey。 |
void deleteValue(java.lang.String valueName) | 刪除一個(gè)命名的值。 |
static java.lang.String expandEnvStrings(java.lang.String exString) | 展開exString中的環(huán)境變量。 |
void export(java.io.PrintWriter out, boolean descend) | 導(dǎo)出key。 |
void finalize() | 重載了的finalize()方法,確保能夠關(guān)閉key。 |
void flushKey() | 確保這個(gè)key被寫到磁盤,對(duì)性能有一定的影響。 |
java.lang.String getDefaultValue() | 得到該key的默認(rèn)值。 |
java.lang.String getFullName() | 得到key的全名。 |
int getMaxSubkeyLength() | 得到所有subkey名稱的最大長(zhǎng)度。 |
int getMaxValueDataLength() | 得到所有subkey值的最大長(zhǎng)度。 |
int getMaxValueNameLength() | 得到所有值的名稱的最大長(zhǎng)度。 |
java.lang.String getName() | 得到該key的名稱。 |
int getNumberSubkeys() | 得到subkey的數(shù)量。 |
int getNumberValues() | 得到值的數(shù)量。 |
java.lang.String getStringValue(java.lang.String valueName) | 得到REG_SZ或REG_EXPAND_SZ的值。 |
RegistryValue getValue(java.lang.String valueName) | 得到valueName的值。 |
boolean hasDefaultValue() | 判斷該key是否有默認(rèn)值。 |
boolean hasOnlyDefaultValue() | 判斷該key是否只有默認(rèn)值。 |
int incrDoubleWord(java.lang.String valueName) | 該方法將增強(qiáng)REG_DWORD的值。 |
java.util.Enumeration keyElements() | 枚舉該key的subkey的名稱。 |
RegistryKey openSubKey(java.lang.String subkey) | 打開該key的subkey,具有寫權(quán)限。 |
RegistryKey openSubKey(java.lang.String subKey, int access) | 打開該key的subkey,具有指定的權(quán)限。 |
java.lang.String regEnumKey(int index) | 得到該key在index處的subkey。 |
java.lang.String regEnumValue(int index) | 得到該key在index處的subkey的值。 |
void setCreated(boolean created) | 設(shè)置該key的created狀態(tài)。 |
void setValue(RegistryValue value) | 設(shè)置該key的值。 |
void setValue(java.lang.String valueName, RegistryValue value) | 設(shè)置valueName的值。 |
java.util.Enumeration valueElements() | 枚舉該key的值的名稱。 |
boolean wasCreated() | 判斷該key是被opened還是被created和opened。 |
最后我們來(lái)看一個(gè)代碼示例:
package org.solol.test; import com.ice.jni.registry.NoSuchKeyException; import com.ice.jni.registry.RegStringValue; import com.ice.jni.registry.Registry; import com.ice.jni.registry.RegistryException; import com.ice.jni.registry.RegistryKey; /** * @author solo L * */ public class JNIRegistryTest { /** * @param args */ public static void main(String[] args) { //創(chuàng)建注冊(cè)表項(xiàng)并設(shè)置相應(yīng)的值 try { RegistryKey software = Registry.HKEY_LOCAL_MACHINE .openSubKey("SOFTWARE"); RegistryKey subKey = software.createSubKey("SubKeyName", ""); subKey.setValue(new RegStringValue(subKey, "subKey1", "subKey1Value")); subKey.setValue(new RegStringValue(subKey, "subKey2", "subKey2Value")); subKey.closeKey(); } catch (NoSuchKeyException e) { e.printStackTrace(); } catch (RegistryException e) { e.printStackTrace(); } //打開注冊(cè)表項(xiàng)并讀出相應(yīng)的值 try { RegistryKey software = Registry.HKEY_LOCAL_MACHINE. openSubKey("SOFTWARE"); RegistryKey subKey = software.openSubKey("SubKeyName"); String subKey1Value = subKey.getStringValue("subKey1"); String subKey2Value = subKey.getStringValue("subKey2"); System.out.println(subKey1Value); System.out.println(subKey2Value); subKey.closeKey(); } catch (NoSuchKeyException e) { e.printStackTrace(); } catch (RegistryException e) { e.printStackTrace(); } } }
創(chuàng)建的注冊(cè)表項(xiàng)如圖所示:
![]()
輸出結(jié)果為:
subKey1Value
subKey2Value
- 用Preferences API存儲(chǔ)對(duì)象,這是一篇來(lái)自IBM的文章可以使您進(jìn)一步了解Preferences API。
- Microsoft Windows 注冊(cè)表說(shuō)明
- Description of the Microsoft Windows registry
- 在JNIRegistry這里可以下載到需要的包和源代碼。
- 如果您想閱讀JNIRegistry的Java doc可以來(lái)這里。
- 在Registry和Registry Reference可以找到關(guān)于注冊(cè)表、注冊(cè)表函數(shù)、注冊(cè)表結(jié)構(gòu)、注冊(cè)表元素大小限制和注冊(cè)表值類型等大量的信息。
說(shuō)明:我的體會(huì)“第一步:把下載下來(lái)的jar包加載到工程內(nèi),第二步,把與jar包在一起的dll文件拷貝到你jdk安裝目錄下\jre\bin文件夾下”