﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-jimmy-随笔分类-java API</title><link>http://www.blogjava.net/jimmy/category/34743.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 20 Sep 2008 03:58:24 GMT</lastBuildDate><pubDate>Sat, 20 Sep 2008 03:58:24 GMT</pubDate><ttl>60</ttl><item><title>java 之 注册表操作篇</title><link>http://www.blogjava.net/jimmy/archive/2008/09/20/230097.html</link><dc:creator>牛X书记</dc:creator><author>牛X书记</author><pubDate>Sat, 20 Sep 2008 02:32:00 GMT</pubDate><guid>http://www.blogjava.net/jimmy/archive/2008/09/20/230097.html</guid><wfw:comment>http://www.blogjava.net/jimmy/comments/230097.html</wfw:comment><comments>http://www.blogjava.net/jimmy/archive/2008/09/20/230097.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jimmy/comments/commentRss/230097.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jimmy/services/trackbacks/230097.html</trackback:ping><description><![CDATA[<p><a name="d3e65"><font color="#666600" size="2"><strong style="color: #ff0000">使用Preferences API</strong></font></a>&nbsp;&nbsp;&nbsp; <a href="http://www.solol.org/technologic/java/j-registry/#resource"><font color="#666600" size="2">参考资料</font></a><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>Preferences的误解</strong>：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先要指明的是：<font size="2">Preferences API并不是为访问Windows注册表而设计的。<br />
<font size="2"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们之所以会有上面的误解是由于Sun的Windows版本的JDK在实现Preferences API时使用了Windows注册表作为存储库，即我们用Preferences API存储的数据会保存到Windows注册表中，这样Preferenes API也就有了访问Windows注册表的能力。但是换到其它的平台或其它厂商的JDK实现又会怎么样呢？这个问题是和Preferences API的实现相关的，我们没有办法回答。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>Preferences适用的条件</strong>：<br />
<font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果程序不关心存储库的细节，只是要找一个存放数据的地方，那么Preferences API很合适。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font size="2"><strong>Preferences API的局限：<br />
</strong><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个Java软件，这次我在Sun的JDK上运行并使用Preferences API保存了我的个人喜好，下次我在IBM的JDK上运行，这时我的个人喜好还可以通过Preferences API得到吗？可能可以也可能不可以，这时的行为是由Sun和IBM的Preferences API实现决定的。（在相同的JDK实现上可以使用Preferences API来在不同的程序间共享数据）</font> <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font size="2">一个Java软件需要让用户设置是否和操作系统一起启动，类似的需求还很多。这类需求就是要求Java程序有真正的和相关操作系统协同的能力。这种能力不是Preferences API的设计目标。</font> <br />
<br />
<a name="d3e98"><font color="#666600" size="2"><strong style="color: #ff0000">使用JNI</strong></font></a>&nbsp;&nbsp;&nbsp; <a href="http://www.solol.org/technologic/java/j-registry/#resource"><font color="#666600" size="2">参考资料</font></a><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font size="2">Windows操作系统提供了操作注册表的API，因此用JNI将Java和这些API连接起来我们就获得了用Java操作注册表的能力。这说起来有些简单，实现起来却需要处理大量的细节。幸运的是这样的工作已经有人做了，我们要感谢他们。下面我们就来看看其中的一个包。<br />
<br />
<font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; com.ice.jni.registry包是通过JNI(Java native interface)实现的Windows注册表操作API，可以用来访问、修改和导出Windows注册表。现在这个包已经公开了，可以放心的使用而不必担心license的问题，并且包括一个构建好的DLL和Java、C的源代码。它可以在Java 1.1和更高的版本上工作。<br />
<br />
<br />
<br />
<font size="2">下面详细的描述一下这个包中的类，数量不是很多：</font><br />
</p>
<ul>
    <li><font size="2">HexNumberFormat 用来格式化和分析十六进制整数。</font>
    <li><font size="2">RegBinaryValue 表示类型为REG_BINARY的注册表值。REG_BINARY是指任意形式的二进制数。</font>
    <li><font size="2">RegDWordValue 表示类型为REG_DWORD的注册表值。REG_DWORD是指一个32位的整数。根据该整数的字节序不同又分为REG_DWORD_LITTLE_ENDIAN和REG_DWORD_BIG_ENDIAN。在Windows中REG_DWORD和REG_DWORD_LITTLE_ENDIAN有相同的含义。</font>
    <li><font size="2">RegistryValue 表示任意类型的注册表值，这是一个抽象类，不能被实例化。</font>
    <li><font size="2">RegMultiStringValue 表示类型为REG_MULTI_SZ的注册表值。REG_MULTI_SZ是一个null-terminated的字符串的序列。</font>
    <li><font size="2">RegStringValue 表示类型为REG_SZ和REG_EXPAND_SZ的注册表值。REG_SZ是指一个null-terminated的字符串，REG_EXPAND_SZ是指一个含有未展开的环境变量的null-terminated的字符串。</font>
    <li><font size="2">Registry 这个类定义了定级项(Key)，包括HKEY_CLASSES_ROOT、HKEY_CURRENT_CONFIG、HKEY_CURRENT_USER、HKEY_DYN_DATA、HKEY_LOCAL_MACHINE、HKEY_PERFORMANCE_DATA和HKEY_USERS。还定义了错误代码，这些错误代码会包含在RegistryException中。最后是一些工具方法，如dumpHexData、exportRegistryKey、getErrorMessage、getTopLevelKey、openSubkey、parseArgumentString、parseArgumentVector、splitString和usage。</font>
    <li><font size="2">RegistryKey 定义了注册表的一个表项(Key)和相关的一些操作。</font> </li>
</ul>
<p><font size="2">RegistryKey的方法概要：</font></p>
<p>
<table style="width: 665px; height: 690px" align="center" border="1">
    <tbody>
        <tr>
            <td><font size="2">方法</font></td>
            <td><font size="2">简短描述</font></td>
        </tr>
        <tr>
            <td><font size="2">void closeKey()</font></td>
            <td><font size="2">关闭该subkey。</font></td>
        </tr>
        <tr>
            <td><font size="2">RegistryKey connectRegistry(java.lang.String hostName)</font></td>
            <td><font size="2">连接远程主机hostName的注册表。</font></td>
        </tr>
        <tr>
            <td><font size="2">RegistryKey createSubKey(java.lang.String subkey, java.lang.String className)</font></td>
            <td><font size="2">创建和打开该key的subkey，具有写权限。</font></td>
        </tr>
        <tr>
            <td><font size="2">RegistryKey createSubKey(java.lang.String subKey, java.lang.String className, int access)</font></td>
            <td><font size="2">创建和打开该key的subkey，具有指定的权限。</font></td>
        </tr>
        <tr>
            <td><font size="2">int decrDoubleWord(java.lang.String valueName)</font></td>
            <td><font size="2">该方法将消减REG_DWORD的值。</font></td>
        </tr>
        <tr>
            <td><font size="2">void deleteSubKey(java.lang.String subKey)</font></td>
            <td><font size="2">删除该subkey。</font></td>
        </tr>
        <tr>
            <td><font size="2">void deleteValue(java.lang.String valueName)</font></td>
            <td><font size="2">删除一个命名的值。</font></td>
        </tr>
        <tr>
            <td><font size="2">static java.lang.String expandEnvStrings(java.lang.String exString)</font></td>
            <td><font size="2">展开exString中的环境变量。</font></td>
        </tr>
        <tr>
            <td><font size="2">void export(java.io.PrintWriter out, boolean descend)</font></td>
            <td><font size="2">导出key。</font></td>
        </tr>
        <tr>
            <td><font size="2">void finalize()</font></td>
            <td><font size="2">重载了的finalize()方法，确保能够关闭key。</font></td>
        </tr>
        <tr>
            <td><font size="2">void flushKey()</font></td>
            <td><font size="2">确保这个key被写到磁盘，对性能有一定的影响。</font></td>
        </tr>
        <tr>
            <td><font size="2">java.lang.String getDefaultValue()</font></td>
            <td><font size="2">得到该key的默认值。</font></td>
        </tr>
        <tr>
            <td><font size="2">java.lang.String getFullName()</font></td>
            <td><font size="2">得到key的全名。</font></td>
        </tr>
        <tr>
            <td><font size="2">int getMaxSubkeyLength()</font></td>
            <td><font size="2">得到所有subkey名称的最大长度。</font></td>
        </tr>
        <tr>
            <td><font size="2">int getMaxValueDataLength()</font></td>
            <td><font size="2">得到所有subkey值的最大长度。</font></td>
        </tr>
        <tr>
            <td><font size="2">int getMaxValueNameLength()</font></td>
            <td><font size="2">得到所有值的名称的最大长度。</font></td>
        </tr>
        <tr>
            <td><font size="2">java.lang.String getName()</font></td>
            <td><font size="2">得到该key的名称。</font></td>
        </tr>
        <tr>
            <td><font size="2">int getNumberSubkeys()</font></td>
            <td><font size="2">得到subkey的数量。</font></td>
        </tr>
        <tr>
            <td><font size="2">int getNumberValues()</font></td>
            <td><font size="2">得到值的数量。</font></td>
        </tr>
        <tr>
            <td><font size="2">java.lang.String getStringValue(java.lang.String valueName)</font></td>
            <td><font size="2">得到REG_SZ或REG_EXPAND_SZ的值。</font></td>
        </tr>
        <tr>
            <td><font size="2">RegistryValue getValue(java.lang.String valueName)</font></td>
            <td><font size="2">得到valueName的值。</font></td>
        </tr>
        <tr>
            <td><font size="2">boolean hasDefaultValue()</font></td>
            <td><font size="2">判断该key是否有默认值。</font></td>
        </tr>
        <tr>
            <td><font size="2">boolean hasOnlyDefaultValue()</font></td>
            <td><font size="2">判断该key是否只有默认值。</font></td>
        </tr>
        <tr>
            <td><font size="2">int incrDoubleWord(java.lang.String valueName)</font></td>
            <td><font size="2">该方法将增强REG_DWORD的值。</font></td>
        </tr>
        <tr>
            <td><font size="2">java.util.Enumeration keyElements()</font></td>
            <td><font size="2">枚举该key的subkey的名称。</font></td>
        </tr>
        <tr>
            <td><font size="2">RegistryKey openSubKey(java.lang.String subkey)</font></td>
            <td><font size="2">打开该key的subkey，具有写权限。</font></td>
        </tr>
        <tr>
            <td><font size="2">RegistryKey openSubKey(java.lang.String subKey, int access)</font></td>
            <td><font size="2">打开该key的subkey，具有指定的权限。</font></td>
        </tr>
        <tr>
            <td><font size="2">java.lang.String regEnumKey(int index)</font></td>
            <td><font size="2">得到该key在index处的subkey。</font></td>
        </tr>
        <tr>
            <td><font size="2">java.lang.String regEnumValue(int index)</font></td>
            <td><font size="2">得到该key在index处的subkey的值。</font></td>
        </tr>
        <tr>
            <td><font size="2">void setCreated(boolean created)</font></td>
            <td><font size="2">设置该key的created状态。</font></td>
        </tr>
        <tr>
            <td><font size="2">void setValue(RegistryValue value)</font></td>
            <td><font size="2">设置该key的值。</font></td>
        </tr>
        <tr>
            <td><font size="2">void setValue(java.lang.String valueName, RegistryValue value)</font></td>
            <td><font size="2">设置valueName的值。</font></td>
        </tr>
        <tr>
            <td><font size="2">java.util.Enumeration valueElements()</font></td>
            <td><font size="2">枚举该key的值的名称。</font></td>
        </tr>
        <tr>
            <td><font size="2">boolean wasCreated()</font></td>
            <td><font size="2">判断该key是被opened还是被created和opened。</font></td>
        </tr>
    </tbody>
</table>
</p>
<p><font size="2"><br />
<br />
最后我们来看一个代码示例：</font></p>
<pre><font size="2">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 {
&nbsp;&nbsp;&nbsp;&nbsp; /**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param args
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //创建注册表项并设置相应的值
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RegistryKey software = Registry.HKEY_LOCAL_MACHINE
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .openSubKey("SOFTWARE");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RegistryKey subKey = software.createSubKey("SubKeyName", "");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subKey.setValue(new RegStringValue(subKey, "subKey1",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "subKey1Value"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subKey.setValue(new RegStringValue(subKey, "subKey2",
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "subKey2Value"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subKey.closeKey();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (NoSuchKeyException e) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (RegistryException e) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //打开注册表项并读出相应的值
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RegistryKey software = Registry.HKEY_LOCAL_MACHINE.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; openSubKey("SOFTWARE");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RegistryKey subKey = software.openSubKey("SubKeyName");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String subKey1Value = subKey.getStringValue("subKey1");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String subKey2Value = subKey.getStringValue("subKey2");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(subKey1Value);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(subKey2Value);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subKey.closeKey();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (NoSuchKeyException e) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (RegistryException e) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp; }
}
</font></pre>
<pre><font size="2">创建的注册表项如图所示：</font><br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/jimmy/reg01.gif" border="0" />
</pre>
<p><font size="2">输出结果为： <br />
<br />
subKey1Value <br />
<br />
subKey2Value </font><br />
<br />
<br />
</p>
<div class="resources"><a name="resource"><font color="#ff00ff" size="2"><u>参考资料</u></font></a><font color="#ff00ff"> </font></div>
<ul>
    <li><a href="http://www-128.ibm.com/developerworks/cn/java/j-prefapi/"><font color="#ff00ff" size="2">用Preferences API存储对象</font></a><font color="#ff00ff"><font size="2">，这是一篇来自IBM的文章可以使您进一步了解Preferences API。</font> </font>
    <li><a href="http://support.microsoft.com/default.aspx?scid=kb;zh-cn;256986"><font color="#ff00ff" size="2">Microsoft Windows 注册表说明</font></a><font color="#ff00ff"> </font>
    <li><a href="http://support.microsoft.com/kb/256986/EN-US/"><font color="#ff00ff" size="2">Description of the Microsoft Windows registry</font></a><font color="#ff00ff"> </font>
    <li><font color="#000000" size="2">在</font><a href="http://www.trustice.com/java/jnireg/index.shtml"><font color="#000000" size="2">JNIRegistry</font></a><font color="#ff00ff"><font color="#000000" size="2">这里可以下载到需要的包和源代码。</font> </font>
    <li><font color="#ff00ff" size="2">如果您想阅读</font><a href="http://www.gjt.org/javadoc/com/ice/jni/registry/package-summary.html"><font color="#ff00ff" size="2">JNIRegistry的Java doc</font></a><font color="#ff00ff"><font size="2">可以来这里。</font> </font>
    <li><font color="#ff00ff" size="2">在</font><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/registry.asp"><font color="#ff00ff" size="2">Registry</font></a><font color="#ff00ff" size="2">和</font><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/registry_reference.asp"><font color="#ff00ff" size="2">Registry Reference</font></a><font color="#ff00ff"><font size="2">可以找到关于注册表、注册表函数、注册表结构、注册表元素大小限制和注册表值类型等大量的信息。</font></font> </li>
</ul>
</font></font>
<p><font color="#0000ff">说明：我的体会&#8220;第一步：把下载下来的jar包加载到工程内，第二步，把与jar包在一起的dll文件拷贝到你jdk安装目录下\jre\bin文件夹下&#8221;</font></p>
</font></font></font></font>
<img src ="http://www.blogjava.net/jimmy/aggbug/230097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jimmy/" target="_blank">牛X书记</a> 2008-09-20 10:32 <a href="http://www.blogjava.net/jimmy/archive/2008/09/20/230097.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>