也就是,中文进去是乱码,中文出来也是乱码
崩溃了,从昨天晚上9点搞到今早3点,这编码解码问题我真是要抓狂了
朋友们帮我瞧瞧啊,不甚感激!!!
废话不多说,直接上代码
package available.registry.test;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import com.ice.jni.registry.NoSuchKeyException;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;
import com.ice.jni.registry.RegistryValue;
// 这个类使用了 registry.jar 中 jni 提供的功能!
public class RegistryManager {
public static void main(String[] args) throws NoSuchKeyException,
RegistryException {
// 提示如何在命令行下使用 registry.jar 文件,参数到底是什么意思?
// Registry.usage("123");
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
RegistryKey registryKey = Registry.openSubkey(
Registry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\",
RegistryKey.ACCESS_READ);
// API 上声称返回的是一个 RegistryKey 类型的枚举,结果死活是String 类型的~
Enumeration<?> enums = registryKey.keyElements();
while (enums.hasMoreElements()) {
String subRKName = (String) enums.nextElement();
System.out.println("之前 " + subRKName);
subRKName = RegistryManager.make8859toGB(subRKName);
System.out.println("之后 " + subRKName);
RegistryKey sub = null;
try {
sub = registryKey.openSubKey(subRKName, RegistryKey.ACCESS_READ);
} catch (com.ice.jni.registry.NoSuchKeyException e) {
System.err.println("找不到这个键!");
}
if (sub != null) {
System.out.println("子键的名字为:" + sub.getName());
RegistryValue rv = sub.getValue("DisplayName");
if (rv != null) {
System.err.println(sub.getName()+" 子键 DisplayName 属性的值为:"+new String(rv.getByteData()));
System.out.println();
}
}
}
}
// iso-8859-1
public static String make8859toGB(String str) {
try {
// String str8859 = URLEncoder.encode(str, "Unicode");
// str8859 = URLDecoder.decode(str, "ASCII");
// String str8859 = URLDecoder.decode(str, "GBK");
// 从第二个参数的格式转换为第一个参数的格式~
String str8859 = new String(str.getBytes("GBK"), "ASCII");
return str8859;
} catch (UnsupportedEncodingException ioe) {
ioe.printStackTrace();
}
return str;
}
}
报错信息为(我装了360杀毒和360安全卫士,中文死活显示为????):
之前 360SD
之后 360SD
子键的名字为:360SD
360SD 子键 DisplayName 属性的值为:360????
之前 360?????¦
之后 360??????W
找不到这个键!
之前 360????????
之后 360????????
之前 Adobe AIR
之后 Adobe AIR
子键的名字为:Adobe AIR
找不到这个键!
之前 Adobe Flash Player ActiveX
之后 Adobe Flash Player ActiveX
子键的名字为:Adobe Flash Player ActiveX
Adobe AIR 子键 DisplayName 属性的值为:Adobe AIR
Adobe Flash Player ActiveX 子键 DisplayName 属性的值为:Adobe Flash Player 10 ActiveX
之前 Adobe Flash Player Plugin
之后 Adobe Flash Player Plugin
子键的名字为:Adobe Flash Player Plugin
之前 Branding
之后 Branding
子键的名字为:Branding
Adobe Flash Player Plugin 子键 DisplayName 属性的值为:Adobe Flash Player 10 Plugin
Exception in thread "main" com.ice.jni.registry.NoSuchValueException: RegQueryValueEx(), value='DisplayName'
at com.ice.jni.registry.RegistryKey.getValue(Native Method)
at available.registry.test.RegistryManager.main(RegistryManager.java:44)
10 个解决方案
#1
神呐,来个人顶顶啊~
#2
应该就是编码的问题吧,
#3
对啊,我也知道是编码的问题啊,哥们儿能不能帮我来看一下,我真的要抓狂了~~
#4
我上传了个dll文件.你替换一下,就可以正常显示中文了.
要传入中文参数应该还有问题.因为我也是参照网上的jni乱码修改的源代码strbufToJString方法.jStringToNewAscii方法修改编译不过去.有时间再弄了.
http://download.csdn.net/source/3182486
上面是dll下载.参照http://www.blogjava.net/mocci/archive/2005/12/08/22946.html的方法写的.
要传入中文参数应该还有问题.因为我也是参照网上的jni乱码修改的源代码strbufToJString方法.jStringToNewAscii方法修改编译不过去.有时间再弄了.
http://download.csdn.net/source/3182486
上面是dll下载.参照http://www.blogjava.net/mocci/archive/2005/12/08/22946.html的方法写的.
#5
楼上正解
之前也遇到过同样的问题,重新编译下那个dll就可以了
之前也遇到过同样的问题,重新编译下那个dll就可以了
#6
/**
* 将dll获取的字符串拼接回原来的形式.
* 因为dll内以前的方法只是单纯的将byte复制到java的char里
* if ( uniBuf != NULL )
{
for ( i = 0 ; i < len ; ++i )
uniBuf[i] = (jchar) buf[i];
result = (*env)->NewString( env, uniBuf, (jsize)len );
free( uniBuf );
}
return result;
* @param str 从dll获取的字符串
* @return
* @throws UnsupportedEncodingException
*/
static String decode(String str) throws UnsupportedEncodingException{
char[] charbuf = str.toCharArray();
byte[] bytebuf = new byte[charbuf.length];
for(int i=0;i<charbuf.length;i++){
bytebuf[i] = (byte)charbuf[i];
}
return new String(bytebuf,"gbk");
}
/**
* 相反要传入中文的字符来操作,需要修改中文为他所识别的乱码...即将中文按两字节一个,拆分开
* @param str
* @return
* @throws UnsupportedEncodingException
*/
static String encode(String str) throws UnsupportedEncodingException{
byte[] bytebuf = str.getBytes("gbk");
char[] charbuf = new char[bytebuf.length];
for(int i=0;i<bytebuf.length;i++){
charbuf[i] = (char)bytebuf[i];
}
return new String(charbuf,0,charbuf.length);
}
subRKName = encode( subRKName );//你看看结果.原理在上面.不用替换dll也可以
#7
就是把编码转换成字节了,楼主确认下是否有问题?
#8
强!!终于解决了这个问题,是在是太感谢了!!
#9
哥们儿这个decode 有点儿问题啊,我插不进去中文啊
我上代码,拜托给我看一下啊,不知不觉又整了几时~
public class CopyOfRegistryManager2 {
public static void main(String[] args) throws NoSuchKeyException,
RegistryException {
RegistryKey registryKey = Registry.openSubkey(
Registry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
RegistryKey.ACCESS_READ);
registryKey.createSubKey(RegistryUtil.decode("成功"), "");
}
}
跑到注册表里面一看,还是乱码 -- 锟
如果哥们儿百忙之中能够抽出一点空来的话,不妨帮我改下代码,我的需求很简单,从注册表中取出所有
安装程序的信息,
也就是遍历 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
的所有子键,取出每个子键的 DisplayName 属性打印出来(子键名有中文,子键的DisplayName属性也包含中文)
我把代码粘上吧
package available.registry.test;
import java.util.Enumeration;
import available.registry.basic.RegistryUtil;
import com.ice.jni.registry.NoSuchKeyException;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;
import com.ice.jni.registry.RegistryValue;
// 这个类使用了 registry.jar 中 jni 提供的功能!
public class RegistryManager {
private final Object o = new Object();
public static void main(String[] args) throws NoSuchKeyException,
RegistryException {
// 提示如何在命令行下使用 registry.jar 文件,参数到底是什么意思?
// Registry.usage("123");
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
RegistryKey rootRK = Registry.openSubkey(
Registry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\",
RegistryKey.ACCESS_READ);
RegistryManager rm = new RegistryManager();
Enumeration<?> enums = rootRK.keyElements();
while (enums.hasMoreElements()) {
synchronized(rm.o) {
String childRKName = (String)enums.nextElement();
String childRKNameDecoded = RegistryUtil.decode(childRKName);
System.err.println("之后 " + childRKNameDecoded);
rm.getDisplayAttr(rootRK, childRKNameDecoded);
}
}
}
// “根键” 和 “枚举出来的子键名”
public synchronized void getDisplayAttr(RegistryKey rootRK, String childRKNameDecoded) throws NoSuchKeyException,
RegistryException {
RegistryKey childRK = null;
try {
childRK = rootRK.openSubKey(RegistryUtil.encode(childRKNameDecoded), RegistryKey.ACCESS_READ);
} catch (com.ice.jni.registry.NoSuchKeyException e) {
System.out.println(childRKNameDecoded + " 找不到这个键!");
}
if(childRK != null) {
// 获取子键的 DisplayName 属性的值
String subKeyName = RegistryUtil.decode(childRK.getName());
System.out.println("子键的名字为:" + subKeyName);
RegistryValue rv = null;
try {
rv = childRK.getValue("DisplayName");
} catch (com.ice.jni.registry.NoSuchValueException e) {
System.err.println("该子键没有这个 DisplayName 这个属性~");
}
if (rv != null) {
System.out.print(childRK.getName()+" 子键 DisplayName 属性的值为:");
String name = RegistryUtil.decode(new String(rv.getByteData()));
if(name == null) {
System.err.println("null");
} else if(name.equals("")) {
System.err.println("equals(\"\")");
} else {
System.err.println(name);
}
System.out.println();
}
}
}
}
#10
package available.registry.basic;
import java.io.UnsupportedEncodingException;
public class RegistryUtil {
/**
* 将dll获取的字符串拼接回原来的形式.
* 因为dll内以前的方法只是单纯的将byte复制到java的char里
* if ( uniBuf != NULL )
{
for ( i = 0 ; i < len ; ++i )
uniBuf[i] = (jchar) buf[i];
result = (*env)->NewString( env, uniBuf, (jsize)len );
free( uniBuf );
}
return result;
* @param str 从dll获取的字符串
* @return
* @throws UnsupportedEncodingException
*/
public static String decode(String str) {
String result = null;
char[] charbuf = str.toCharArray();
byte[] bytebuf = new byte[charbuf.length];
for(int i=0;i<charbuf.length;i++){
bytebuf[i] = (byte)charbuf[i];
}
try {
result = new String(bytebuf,"GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* 相反要传入中文的字符来操作,需要修改中文为他所识别的乱码...即将中文按两字节一个,拆分开
* @param str
* @return
*/
public static String encode(String str) {
byte[] bytebuf = null;
try {
bytebuf = str.getBytes("GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
char[] charbuf = new char[bytebuf.length];
for(int i=0;i<bytebuf.length;i++){
charbuf[i] = (char)bytebuf[i];
}
return new String(charbuf,0,charbuf.length);
}
}
#1
神呐,来个人顶顶啊~
#2
应该就是编码的问题吧,
#3
对啊,我也知道是编码的问题啊,哥们儿能不能帮我来看一下,我真的要抓狂了~~
#4
我上传了个dll文件.你替换一下,就可以正常显示中文了.
要传入中文参数应该还有问题.因为我也是参照网上的jni乱码修改的源代码strbufToJString方法.jStringToNewAscii方法修改编译不过去.有时间再弄了.
http://download.csdn.net/source/3182486
上面是dll下载.参照http://www.blogjava.net/mocci/archive/2005/12/08/22946.html的方法写的.
要传入中文参数应该还有问题.因为我也是参照网上的jni乱码修改的源代码strbufToJString方法.jStringToNewAscii方法修改编译不过去.有时间再弄了.
http://download.csdn.net/source/3182486
上面是dll下载.参照http://www.blogjava.net/mocci/archive/2005/12/08/22946.html的方法写的.
#5
楼上正解
之前也遇到过同样的问题,重新编译下那个dll就可以了
之前也遇到过同样的问题,重新编译下那个dll就可以了
#6
/**
* 将dll获取的字符串拼接回原来的形式.
* 因为dll内以前的方法只是单纯的将byte复制到java的char里
* if ( uniBuf != NULL )
{
for ( i = 0 ; i < len ; ++i )
uniBuf[i] = (jchar) buf[i];
result = (*env)->NewString( env, uniBuf, (jsize)len );
free( uniBuf );
}
return result;
* @param str 从dll获取的字符串
* @return
* @throws UnsupportedEncodingException
*/
static String decode(String str) throws UnsupportedEncodingException{
char[] charbuf = str.toCharArray();
byte[] bytebuf = new byte[charbuf.length];
for(int i=0;i<charbuf.length;i++){
bytebuf[i] = (byte)charbuf[i];
}
return new String(bytebuf,"gbk");
}
/**
* 相反要传入中文的字符来操作,需要修改中文为他所识别的乱码...即将中文按两字节一个,拆分开
* @param str
* @return
* @throws UnsupportedEncodingException
*/
static String encode(String str) throws UnsupportedEncodingException{
byte[] bytebuf = str.getBytes("gbk");
char[] charbuf = new char[bytebuf.length];
for(int i=0;i<bytebuf.length;i++){
charbuf[i] = (char)bytebuf[i];
}
return new String(charbuf,0,charbuf.length);
}
subRKName = encode( subRKName );//你看看结果.原理在上面.不用替换dll也可以
#7
就是把编码转换成字节了,楼主确认下是否有问题?
#8
强!!终于解决了这个问题,是在是太感谢了!!
#9
哥们儿这个decode 有点儿问题啊,我插不进去中文啊
我上代码,拜托给我看一下啊,不知不觉又整了几时~
public class CopyOfRegistryManager2 {
public static void main(String[] args) throws NoSuchKeyException,
RegistryException {
RegistryKey registryKey = Registry.openSubkey(
Registry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
RegistryKey.ACCESS_READ);
registryKey.createSubKey(RegistryUtil.decode("成功"), "");
}
}
跑到注册表里面一看,还是乱码 -- 锟
如果哥们儿百忙之中能够抽出一点空来的话,不妨帮我改下代码,我的需求很简单,从注册表中取出所有
安装程序的信息,
也就是遍历 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
的所有子键,取出每个子键的 DisplayName 属性打印出来(子键名有中文,子键的DisplayName属性也包含中文)
我把代码粘上吧
package available.registry.test;
import java.util.Enumeration;
import available.registry.basic.RegistryUtil;
import com.ice.jni.registry.NoSuchKeyException;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;
import com.ice.jni.registry.RegistryValue;
// 这个类使用了 registry.jar 中 jni 提供的功能!
public class RegistryManager {
private final Object o = new Object();
public static void main(String[] args) throws NoSuchKeyException,
RegistryException {
// 提示如何在命令行下使用 registry.jar 文件,参数到底是什么意思?
// Registry.usage("123");
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
RegistryKey rootRK = Registry.openSubkey(
Registry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\",
RegistryKey.ACCESS_READ);
RegistryManager rm = new RegistryManager();
Enumeration<?> enums = rootRK.keyElements();
while (enums.hasMoreElements()) {
synchronized(rm.o) {
String childRKName = (String)enums.nextElement();
String childRKNameDecoded = RegistryUtil.decode(childRKName);
System.err.println("之后 " + childRKNameDecoded);
rm.getDisplayAttr(rootRK, childRKNameDecoded);
}
}
}
// “根键” 和 “枚举出来的子键名”
public synchronized void getDisplayAttr(RegistryKey rootRK, String childRKNameDecoded) throws NoSuchKeyException,
RegistryException {
RegistryKey childRK = null;
try {
childRK = rootRK.openSubKey(RegistryUtil.encode(childRKNameDecoded), RegistryKey.ACCESS_READ);
} catch (com.ice.jni.registry.NoSuchKeyException e) {
System.out.println(childRKNameDecoded + " 找不到这个键!");
}
if(childRK != null) {
// 获取子键的 DisplayName 属性的值
String subKeyName = RegistryUtil.decode(childRK.getName());
System.out.println("子键的名字为:" + subKeyName);
RegistryValue rv = null;
try {
rv = childRK.getValue("DisplayName");
} catch (com.ice.jni.registry.NoSuchValueException e) {
System.err.println("该子键没有这个 DisplayName 这个属性~");
}
if (rv != null) {
System.out.print(childRK.getName()+" 子键 DisplayName 属性的值为:");
String name = RegistryUtil.decode(new String(rv.getByteData()));
if(name == null) {
System.err.println("null");
} else if(name.equals("")) {
System.err.println("equals(\"\")");
} else {
System.err.println(name);
}
System.out.println();
}
}
}
}
#10
package available.registry.basic;
import java.io.UnsupportedEncodingException;
public class RegistryUtil {
/**
* 将dll获取的字符串拼接回原来的形式.
* 因为dll内以前的方法只是单纯的将byte复制到java的char里
* if ( uniBuf != NULL )
{
for ( i = 0 ; i < len ; ++i )
uniBuf[i] = (jchar) buf[i];
result = (*env)->NewString( env, uniBuf, (jsize)len );
free( uniBuf );
}
return result;
* @param str 从dll获取的字符串
* @return
* @throws UnsupportedEncodingException
*/
public static String decode(String str) {
String result = null;
char[] charbuf = str.toCharArray();
byte[] bytebuf = new byte[charbuf.length];
for(int i=0;i<charbuf.length;i++){
bytebuf[i] = (byte)charbuf[i];
}
try {
result = new String(bytebuf,"GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* 相反要传入中文的字符来操作,需要修改中文为他所识别的乱码...即将中文按两字节一个,拆分开
* @param str
* @return
*/
public static String encode(String str) {
byte[] bytebuf = null;
try {
bytebuf = str.getBytes("GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
char[] charbuf = new char[bytebuf.length];
for(int i=0;i<bytebuf.length;i++){
charbuf[i] = (char)bytebuf[i];
}
return new String(charbuf,0,charbuf.length);
}
}