oracle和java之间的UTF-8区别

时间:2015-12-11 15:59:00

标签: java oracle unicode utf-8

我在oracle数据库和Java之间有以下unicode差异。

如果我在oracle sql developer中运行以下命令:

select unistr('\008C') from dual;

我得到以下unicode字符: http://www.utf8icons.com/character/140/control-character

但是,如果我尝试在java中执行相同类型的unicode代码到字符串转换:

String s1 = new String("\u008C");

结果我得到一个空字符。

我知道我可以使用\ u0152字符在java和oracle中正确显示我需要的字符,但我想了解为什么我有这个区别。我尝试使用我的字体,但我没有得到任何体面的结果。感谢。

2 个答案:

答案 0 :(得分:1)

这没有任何意义:

String s1 = new String("\u008C".getBytes(), "UTF-8");

如果你很幸运,你的默认编码将是UTF-8,你会得到:

s1.equals("\u008C") == true

这是因为.getBytes()将默认为您的系统编码。您可以有效地编码为UTF-8的未知(但可发现)编码和解码。

如果你运气不好,你的默认编码就是其他的东西,你就会用你的字符串表达。

如果您的意思是:

 System.out.println( "\u008C" );

什么都不产生,这是因为'PARTIAL LINE BACKWARD'是一个控制角色。即它不打印。永远不应该打印。似乎某些UI会自动将此字符渲染为“LATIN CAPITAL LIGATURE OE”(U + 0152)并依赖于实现。

例如,如果我复制创建一个包含Œ的HTML文档,它会在Chrome中显示为Œ。将此char复制到剪贴板并粘贴到文档中并将其另存为UTF-16 BE。十六进制转储文件,您将看到:

0000000 01 52 

'LATIN CAPITAL LIGATURE OE'的Unicode代码点/ UTF-16编码。因此,Oracle SQL Developer工具只是通过显示“LATIN CAPITAL LIGATURE OE”来欺骗/帮助您。

答案 1 :(得分:1)

String.getBytes()使用平台默认编码将字符串转换为字节序列。它相当于:

String encoding = System.getProperty("file.encoding");
"\u008C".getBytes( encoding );

此功能的结果取决于您拥有的编码。

例如,在我的电脑上有cp1250代码页,我得到了这个结果:

    System.out.println( System.getProperty("file.encoding") );
    byte b[] = "\u008C".getBytes();
    for( byte bb: b)System.out.format("%x\n", bb);
    -------
    Cp1250
    3f

如您所见,Œ字符被转换为一个字节:3f,在cp1250中是?字符。我相信这是因为cp1250中没有Œ字符,所以CharsetEncoder(由toBytes()方法用来将unicode字符串转换为specufic charset)将Œ转换为?在这种情况下。

有关详细信息,请参见此处:http://docs.oracle.com/javase/7/docs/api/java/nio/charset/CharsetEncoder.html

如您所见,您的java代码将unicode字符串转换为您的平台编码,然后结果(作为字节数组)再次被视为unicode - 但实际上它是使用其他编码进行编码的。 这没有意义。