在java中转换字符串编码

时间:2011-04-28 01:16:21

标签: java character-encoding

与此问题相关:"Fix" String encoding in Java

我的项目编码是UTF-8。

我需要查询使用特定varchar编码的数据库(显然是EUC-KR)。

我将输入视为UTF-8,并且我想使用该字符串的EUC-KR编码版本进行数据库查询。

首先,我可以使用以下方法选择并显示编码的字符串:

ResultSet rs = stmt.executeQuery("SELECT name FROM mytable");
while(rs.next())
    System.out.println(new String(rs.getBytes(1), "EUC-KR"));

我想做类似的事情:

PreparedStatement ps = conn.prepareStatement("SELECT * FROM MYTABLE WHERE NAME=?");
ps.setString(1,input);
ResultSet rs = ps.executeQuery();

这显然不起作用,因为我的Java程序没有使用与DB相同的编码。所以,我尝试用以下各项替换中间线,但无济于事:

ps.setString(1,new String(input.getBytes("EUC-KR")));
ps.setString(1,new String(input.getBytes("EUC-KR"), "EUC-KR"));
ps.setString(1,new String(input.getBytes("UTF-8"), "EUC-KR"));
ps.setString(1,new String(input.getBytes("EUC-KR"), "UTF-8"));

我正在使用 Oracle 10g 10.1.0

我的尝试的更多细节如下:

似乎工作的是将第一个查询中的名称保存到字符串中而不进行任何其他操作,并将其作为参数传回。它匹配自己。

即,

ResultSet rs = stmt.executeQuery("SELECT name FROM mytable");
rs.next();
String myString = rs.getString(1);
PreparedStatement ps = conn.prepareStatement("SELECT * FROM mytable WHERE name=?");
ps.setString(1, myString);
rs = ps.executeQuery();

...将在rs中输入1个正确的条目。太好了,所以现在我只需要将输入转换为事物似乎的任何格式。

然而,当我尝试使用

读取字节时,我所尝试的任何内容似乎都与“正确”字符串匹配
byte[] mybytearray = myString.getBytes();
for(byte b : mybytearray)
    System.out.print(b+" ");

换句话说,我可以将°í»ê变成고산但我似乎无法将고산变成°í»ê

给出的字节数组
rs.getBytes(1)

与以下任何一个字节数组不同:

rs.getString(1).getBytes()
rs.getString(1).getBytes("UTF8")
rs.getString(1).getBytes("EUC-KR")

不满:事实证明,对于我的数据库,NLS_CHARACTERSET = US7ASCII

这意味着我正在尝试做的事情是不受支持的。感谢大家:(

3 个答案:

答案 0 :(得分:6)

使用String构造函数无法完成任何操作。 String内部始终是UTF-16。将UTF-16字符转换为EUC-KR并再次返回将无济于事。

将无效的Unicode放入String值,希望它们转换为EUC-KR是一个非常糟糕的主意。

你正在做的事情应该是“正常工作”。 oracle驱动程序应该与服务器通信,找到所需的字符集,然后从那里开始。

然而,数据库字符集是什么?如果有人在没有将字符集设置为EUC-KR的情况下存储EUC-KR,那么您或多或少就是一条小溪。

您需要做的是告诉您的jdbc驱动程序用于与服务器通信的字符集。您没有提到如果您使用的是Thin或OCI,答案可​​能会有所不同。

http://download.oracle.com/docs/cd/E14072_01/appdev.112/e13995/oracle/jdbc/OracleDriver.html判断,您可能想尝试启用defaultNChar。

通常,jdbc驱动程序的工作是将String转码为Oracle服务器所需的内容。如果您使用'OCI',则可能需要tnsnames.ora选项。

修改

OP报告数据库的nls_charset是US7ASCII。这意味着所有JDBC驱动程序都会认为将Unicode String值转换为ASCII是他们的工作。韩文字符会减少到?最好。那么,正式地说,你已经上了一条小溪。

有一些可能的尝试。

是一个非常危险的伎俩
 new String(string.getBytes("EUC-KR"), "ascii")

将尝试创建一个Unicode字符串,恰好恰好具有EUC-KR的低字节值。我的信念是,这会破坏数据,但你可以试验。

或者,也许是ps.setBytes(n, string.getBytes("EUC-KR")),但我自己也不知道Oracle是否将字节转换为chars作为二进制副本。它可能。或者,也许,添加一个以blob作为参数的存储过程。

真的,这里要求的是修复数据库以使用UTF-8或EUC-KR的nls_charset,但这是另一项工作。

答案 1 :(得分:0)

你看过charset的正确名称了吗?也许你应该使用UTF8和EUC_KR ..

http://download.oracle.com/javase/1.4.2/docs/guide/intl/encoding.doc.html

答案 2 :(得分:0)

希望这不是一个愚蠢的答案,但你确定charsets.jar在你的类路径中。默认情况下,请参阅this page了解更多信息......

  

charsets.jar文件是JRE的可选功能。要安装它,您必须选择“自定义安装”并选择“支持其他语言环境”功能。