需求: 在JAVA中编写.bat命令来实现对MySQL的导入和导出。但是.bat命令中需要有MySQL的具体地址,而不同的服务器MySQL的地址可能不一样,如果写死的话那每次部署到新的服务器中还要修改class代码,所以考虑写一个监听器来获取该服务器中MySQL的位置,有两种方法:
1)迭代服务器的文件夹,找到MySQL文件夹的位置。
public static void main(String[] args) { System.out.println(search(new File("test.txt"), new File("D:/"))); } // 返回所有与 test 同名的文件或文件夹 static List<File> search(File wanted, File dirToStartFrom) { List<File> matches = new ArrayList<File>(); for (File file: dirToStartFrom.listFiles()) if (new File(file.getName()).equals(wanted)) // 让 equals 方法做跨平台的判断 matches.add(file); else if (file.listFiles() != null) // 只处理可访问的文件夹 matches.addAll(search(wanted, file)); return matches; }
这种方式可行,但是迭代所有文件夹效率太慢。
2)通过注册表来找到安装文件的位置。
可以通过java.util.prefs.* 中的包,但是该包只可以在 HKEY_LOCAL_MACHINE\Software\JavaSoft\prefs和HKEY_LOCAL_USER\Software\JavaSoft\prefs 位置下进行注册表的读写,对其他位置操作就不方便,因为定死了root只能在以上两个位置。这种方法唯一的缺点就是不可以选择在注册表的哪个节点下写入键值!
但是可以通过开源的com.ice.jni.registry包来实现对任意位置的注册表进行操作。
首先在http://www.trustice.com/java/jnireg/index.shtml这里可以下载到需要的包和源代码。第一步:把下载下来的jar包加载到工程内,第二步,把与jar包在一起的dll文件拷贝到你jdk安装目录下\jre\bin文件夹下”
代码示例:
public static void main(String[] args) {
//创建注册表项并设置相应的值
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();
}
//打开注册表项并读出相应的值
try {
RegistryKey software = Registry.HKEY_LOCAL_MACHINE.
openSubKey("SOFTWARE");
RegistryKey subKey = software.openSubKey("MySQL AB");
RegistryKey mysql = subKey.openSubKey("MySQL Server 5.1");
String mysqlLocation = mysql.getStringValue("Location");
System.out.println(mysqlLocation);
subKey.closeKey();
} catch (NoSuchKeyException e) {
e.printStackTrace();
} catch (RegistryException e) {
e.printStackTrace();
}
}
下面详细的描述一下这个该包中的类,数量不是很多:
- HexNumberFormat 用来格式化和分析十六进制整数。
- RegBinaryValue 表示类型为REG_BINARY的注册表值。REG_BINARY是指任意形式的二进制数。
- RegDWordValue 表示类型为REG_DWORD的注册表值。REG_DWORD是指一个32位的整数。根据该整数的字节序不同又分为REG_DWORD_LITTLE_ENDIAN和REG_DWORD_BIG_ENDIAN。在Windows中REG_DWORD和REG_DWORD_LITTLE_ENDIAN有相同的含义。
- RegistryValue 表示任意类型的注册表值,这是一个抽象类,不能被实例化。
- RegMultiStringValue 表示类型为REG_MULTI_SZ的注册表值。REG_MULTI_SZ是一个null-terminated的字符串的序列。
- RegStringValue 表示类型为REG_SZ和REG_EXPAND_SZ的注册表值。REG_SZ是指一个null-terminated的字符串,REG_EXPAND_SZ是指一个含有未展开的环境变量的null-terminated的字符串。
- 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。
- RegistryKey 定义了注册表的一个表项(Key)和相关的一些操作。
RegistryKey的方法概要:
方法 | 简短描述 |
void closeKey() | 关闭该subkey。 |
RegistryKey connectRegistry(java.lang.String hostName) | 连接远程主机hostName的注册表。 |
RegistryKey createSubKey(java.lang.String subkey, java.lang.String className) | 创建和打开该key的subkey,具有写权限。 |
RegistryKey createSubKey(java.lang.String subKey, java.lang.String className, int access) | 创建和打开该key的subkey,具有指定的权限。 |
int decrDoubleWord(java.lang.String valueName) | 该方法将消减REG_DWORD的值。 |
void deleteSubKey(java.lang.String subKey) | 删除该subkey。 |
void deleteValue(java.lang.String valueName) | 删除一个命名的值。 |
static java.lang.String expandEnvStrings(java.lang.String exString) | 展开exString中的环境变量。 |
void export(java.io.PrintWriter out, boolean descend) | 导出key。 |
void finalize() | 重载了的finalize()方法,确保能够关闭key。 |
void flushKey() | 确保这个key被写到磁盘,对性能有一定的影响。 |
java.lang.String getDefaultValue() | 得到该key的默认值。 |
java.lang.String getFullName() | 得到key的全名。 |
int getMaxSubkeyLength() | 得到所有subkey名称的最大长度。 |
int getMaxValueDataLength() | 得到所有subkey值的最大长度。 |
int getMaxValueNameLength() | 得到所有值的名称的最大长度。 |
java.lang.String getName() | 得到该key的名称。 |
int getNumberSubkeys() | 得到subkey的数量。 |
int getNumberValues() | 得到值的数量。 |
java.lang.String getStringValue(java.lang.String valueName) | 得到REG_SZ或REG_EXPAND_SZ的值。 |
RegistryValue getValue(java.lang.String valueName) | 得到valueName的值。 |
boolean hasDefaultValue() | 判断该key是否有默认值。 |
boolean hasOnlyDefaultValue() | 判断该key是否只有默认值。 |
int incrDoubleWord(java.lang.String valueName) | 该方法将增强REG_DWORD的值。 |
java.util.Enumeration keyElements() | 枚举该key的subkey的名称。 |
RegistryKey openSubKey(java.lang.String subkey) | 打开该key的subkey,具有写权限。 |
RegistryKey openSubKey(java.lang.String subKey, int access) | 打开该key的subkey,具有指定的权限。 |
java.lang.String regEnumKey(int index) | 得到该key在index处的subkey。 |
java.lang.String regEnumValue(int index) | 得到该key在index处的subkey的值。 |
void setCreated(boolean created) | 设置该key的created状态。 |
void setValue(RegistryValue value) | 设置该key的值。 |
void setValue(java.lang.String valueName, RegistryValue value) | 设置valueName的值。 |
java.util.Enumeration valueElements() | 枚举该key的值的名称。 |
boolean wasCreated() | 判断该key是被opened还是被created和opened。 |