`

日文字符中常见的乱码情况---正波浪线“~”

阅读更多

在一般的日文字符表示正常的情况下正波浪线“~”任然经常会出现乱码的情况。

数据库参数NLS Database Parameters
NLS_CHARACTERSET                      JA16SJIS
NLS_NCHAR_CHARACTERSET      AL16UTF16

一:对于VARCHAR2字段
现象:在页面上输入“~”存入DB后再取出到页面时变成“?”(页面的字符设置为charset=shift-jis)
调查:
1 页面提交后在java中观察编码为\uff5e
2 java中定义一个字符变量“~”观察编码为\uff5e
3 编码为\uff5e的字符存入数据库再取出的编码为\u301c
4 用Object Browser观察数据库中字符都正常
结论:存入数据库时编码发生了变化\uff5e ---> \u301c
解决:取出数据时遍历发现\u301c就转换为\uff5e
         public String getString(int columnIndex) throws SQLException {
            // TODO: ~を変更
            String value = rs.getString(columnIndex);
            if (value != null){
                 StringBuffer sbDest = new StringBuffer();
                 char ch;
                 for(int j= 0;j< value.length();j++){
                     ch = value.charAt(j);
                     if(ch == 0x301c){
                         sbDest.append("\uff5e"); // ~
                     }else{
                         sbDest.append(ch);
                     }
                 }
                 value = sbDest.toString();
            }

            return value;
        }

二:对于NVARCHAR2字段
现象:在页面上输入正波浪线“~”存入DB后再取出到页面时变成反波浪线“〜”(页面的字符设置为charset=UTF-8)
用Object Browser工具察看表中的数据 发现是正波浪线“~” 编码为\u301c。(实际上用Object Browser看\u301c     \uff5e都是正波浪线)
如果用NVARCHAR2字段,那么正确的操作后可以存入\uff5e

试验用表 Products ,表中的列定义如下所示
id - VARCHAR2(10) — 产品 id
lang_id — VARCHAR2(10) — 语言 id
description — NVARCHAR2(2000) — Unicode 编码的产品描述

JDBC 允许 Java 程序访问 Oracle9i 数据库中的 NVARCHAR2 数据类型的列。Oracle JDBC 驱动程序把 SQL NCHAR/NVARCHAR2 列中的数据从本地字符集编码(UTF8 或 AL16UTF16)直接转化为 UTF-16 编码的 Java 字符串。
为此,我们需要把 Java 字符串绑定到一个 NVARCHAR2 列。下面的代码段显示了完成这项任务的代码。

// Get an Oracle preparedstatement
OraclePreparedStatement orastmt =(OraclePreparedStatement)connection.prepareStatement(
"INSERT INTO PRODUCTS VALUES(?,?,?)");
// Bind the 3rd parameter to NVARCHAR2 form so that the data is stored as unicode
orastmt.setFormOfUse(3,OraclePreparedStatement.FORM_NCHAR);
orastmt.setString(1,product.getId());
orastmt.setString(2,product.getLangId());
orastmt.setString(3,product.getDescription());
orastmt.executeUpdate();
orastmt.close();

使用 orastmt.setFormOfUse() 方法来指定列的类型是 NVARCHAR2。确保数据以Unicode 编码存储。

关于NVARCHAR2字段的操作参考:
http://www.oracle.com/technology/sample_code/tech/java/sqlj_jdbc/files/9i_jdbc/NCHARsupport4UnicodeSample/Readme.html

注意这段话:
The only difference in usage between the SQL CHAR and SQL NCHAR datatypes occur in a data bind situation.
The JDBC program must call the setFormOfUse() method to specify if the data is bound for a SQL NCHAR
datatype and it must be called before binding Java variables to SQL NCHAR datatypes.
必须先setFormOfUse再绑定变量。否则存入数据库中的仍是\u301c

Java and Unicode  

 

        一直以来都被Java编程中出现的乱码问题搞得很头痛,不过今天终于有了更深的理解。 其实很简单,Java中的字符都是以Unicode(UTF-16)形式存储的,即使你调用了new String("\uff5e".getBytes("MS932" , "SJIS" ;这样的语句,其实也并非真的就把这个字符从MS932转换成了SJIS编码形式, 只不过是从一个Unicode(MS932编码的全角波浪线在Unicode中对应的字符)变成了SJIS编码的全角波浪线在Unicode中对应的字 符,说白了,转换后还是个Unicode字符。

        但是为什么仍然会出乱码呢?举个简单的例子,某个终端只接受SJIS编码的字符(目前好象还没有哪个终端支持Unicode吧?),如果你通过Java程 序给它传了一个SJIS中该字符在Unicode中对应的字符,那么底层系统可以顺利地将之转换成正确的SJIS编码字符,于是这个终端也就可以正常显示 该字符了;反之,如果你给了一个MS932中该字符在Unicode中对应的字符,而如果它恰好又是一个特殊字符(比如日文中的全角波浪线''~''), 就会出现乱码(因为MS932编码的全角波浪线在Unicode中对应''\uff5e'',而SJIS编码的全角波浪线在Unicode中对应'' \u301c''),示意如下:

''\uff5e''(Unicode,Java程序) -> ?(本地字符集SJIS,终端):NG。因为Unicode字符''\uff5e''并不对应SJIS字符集中的全角波浪线;
''\u301c''(Unicode,Java程序) -> ~(本地字符集SJIS,终端):OK。
        另外,查看了一下Oracle的JDBC驱动(JDBC OCI driver)的说明,中间提到: "If NLS_LANG specifies a character set other than US7ASCII or WE8ISO8859P1, the driver uses UTF-8 as the client character set. This happens automatically and does not require any user intervention. OCI converts the data from the database character set to UTF-8. The JDBC OCI driver then passes the UTF-8 data to the JDBC Class Library, where the UTF-8 data is converted into UTF-16."那么,按照上面的说法,其实在从数据库取得的字符变成UTF-8时就已经是Unicode字符了,不过这里有一个值得注意的地方,即这个 Unicode字符应该是该本地字符(比如在Oracle服务器的NSL_LANG中指定的EUCJIS)对应的Unicode字符,有些拗口吧?:-) 仍以日文中的全角波浪线为例(假设Oracle服务器的编码是EUCJIS),该转换过程就是:

   ''~''(EUCJIS编码的全角波浪线,Oracle服务器端) -> EUCJIS编码的全角波浪线在UTF-8中对应的字符(UTF-8,经过OCI变换后) -> ''\u301c''(EUCJIS编码的全角波浪线在UTF-16中对应的字符,经过JDBC Class Library变换后)

        最后,还有一个地方须要特别注意:那就是同一个本地字符向Unicode转换过程中,如果使用了不同的映射表,可能会得出不同的结果。以减号 ''-''(MINUS SIGN)从EUCJIS到Unicode的转换过程为例:

0xA1D0(MINUS SIGN/負符号,減算記号) -> ''\u2212''(MINUS SIGN) (使用x-eucjp-unicode-0.9映射表)
0xA1D0(MINUS SIGN/負符号,減算記号) -> ''\u2212''(MINUS SIGN) (使用x-eucjp-jisx0221-1995映射表)
0xA1D0(MINUS SIGN/負符号,減算記号) -> ''\uff0d''(FULLWIDTH HYPHEN-MINUS) (使用x-eucjp-open-19970715-ms映射表)

分享到:
评论

相关推荐

    自制中文系统下 日文乱码小工具

    总之,"自制中文系统下 日文乱码小工具" 解决了跨语言环境中的一个重要问题,使得在中文操作系统下处理日文文本变得更加方便。通过理解字符编码的工作原理和这个工具的功能,我们可以更好地应对类似的问题,并提高...

    日文乱码解决利器

    标题中的“日文乱码解决利器”指的是针对中文系统下显示日文文本出现乱码问题的一种解决方案。在处理跨语言的计算机系统时,尤其是中文系统显示非中文字符集(如日文)时,由于编码不匹配,往往会出现乱码现象。这种...

    日文乱码转换工具

    日文乱码尤其常见,因为日语使用了多种字符集,包括平假名、片假名和汉字,这些字符在不同的编码标准(如Shift-JIS、EUC-JP、UTF-8等)中有不同的表示方式。 【描述】提到的"Locale Emulator 2.4.0.0官方版"是一个...

    解决PLC程序简繁日文乱码.rar

    描述中的“解决PLC程序简繁日文乱码”进一步确认了问题的核心是关于在PLC程序中处理中文字符时出现的乱码现象。标签“软件”表明这个问题可能与特定的软件工具或编程环境有关。压缩包内的文件“Microsoft AppLocale ...

    impala中substr()截取中文字符串乱码的问题

    然而,当涉及到处理中文字符时,Impala的内置函数`substr()`和`substring()`可能会遇到一些挑战,尤其是在截取中文字符串时可能出现乱码问题。这是因为这两个函数在设计时可能没有充分考虑多字节字符集,如UTF-8,而...

    韩文、日文、繁体字的字符集,及字符集介绍

    相比之下,UTF-8作为Unicode的一部分,能涵盖几乎所有的繁体汉字,包括一些罕见和古代的字符,因此在现代网络和软件应用中更为常见。 字符集的选择不仅影响到字符的正确显示,还涉及到编码转换、文本处理和数据交换...

    简体汉字转日文汉字(GB2Shift-JIS) 版本1.0 适用于 MD 机 OpenMG Jukebox 碟名及歌名日文汉字的输入

    简体汉字转日文汉字(GB2Shift-JIS) 版本1.0(适用于 SONY Net-MD 机 OpenMG Jukebox 碟名及歌名日文汉字的输入)

    microsoft去软件显示乱码---免费

    在IT领域,尤其是在多语言环境下,软件显示乱码是一个常见的问题。这主要涉及到字符编码的兼容性和一致性。本文将深入探讨“microsoft去软件显示乱码”这一工具如何解决中文软件在非中文操作系统中出现的乱码问题,...

    日文版WZR-HP-G300NH刷中文官方固件方法

    1. **USB转TTL线**:这是用来连接路由器并进行刷机操作的必备硬件,通过它你可以与路由器的串口通信。 2. **Tftp服务器软件**:如附件中的tftpd32程序,这将在刷机过程中用来传输固件文件到路由器。 刷机步骤如下:...

    中文系统中打开日文CSV文件不乱码.xlsm

    在中文系统中用Excel打开日文ANSI编码的CSV或TXT文件不乱码。 在日文系统中用Excel打开中文ANSI编码的CSV或TXT文件不乱码。 我自己写的:)

    DSOframer源码,解决日文乱码问题

    在处理多语言字符,尤其是非ASCII字符集如日文的UTF-8编码时,软件开发中经常遇到乱码问题。这通常由于以下几个原因: 1. **编码不匹配**:文件或数据库的编码格式与应用程序期望的编码格式不一致。例如,如果数据...

    NOTES日文版中中文显示乱码

    在使用NOTES日文版时,遇到中文显示乱码的问题可能是由于编码不匹配、字符集支持不足或系统设置不当等因素导致的。以下是一些解决NOTES日文版中中文显示乱码问题的方法: 1. **检查字符集设置**:NOTES客户端与...

    sourceinsight 日文注释乱码问题解决

    然而,当涉及到非英文字符,如日文注释时,可能会出现乱码问题,这会严重影响代码的阅读和理解。本文将深入探讨如何解决Source Insight中的日文注释乱码问题。 首先,我们需要了解乱码问题的根源。通常,乱码是由于...

    Serv-U完美解决中日韩文件(夹)名显示乱码

    然而,在处理包含中文、日文或韩文等非ASCII字符的文件和文件夹名称时,由于编码不兼容或者配置不当,可能会导致在客户端看到乱码。这种问题不仅影响了文件的正常浏览和管理,也可能导致文件操作错误,如误删或上传...

    ZXing 2.1版GBK中文乱码解决办法

    在2.1版本中,解码的定义不在这个类中了,挪到了StringUtils类中,所以需要修改这个类,在修改过程中发现,中文被优先转移成日文了。 所以需要挪动一下原类中的代码顺序。 使用方法,直接用两个类,把原来的类给...

    南极星乱码转换器(简体/繁体/日文/韩文乱码转换工具)FOR WINDOWS9X

    在Windows 9X系统中,由于其对Unicode支持有限,尤其是在处理非ASCII字符集如繁体中文、日文和韩文时,可能会出现显示为不可读的乱码。南极星乱码转换器通过内建的编码转换算法,将这些乱码转化为可读的文字,从而...

    日文用的FPDF,用于PHP导出PDF,解决了日文乱码问题!

    2. **字体支持**:默认情况下,FPDF仅支持几种基本的内置字体,如Helvetica、Times和Courier,这些字体不包含日文字符。为了在PDF中显示日文,必须引入支持Unicode的TrueType字体,或者使用扩展如TCPDF或mPDF,它们...

    tera term中文乱码问题

    然而,在使用Tera Term时,尤其是处理中文字符时,可能会遇到中文乱码的问题。这不仅影响工作效率,还可能导致数据误解。本文将深入探讨这个问题,并提供解决方案。 首先,我们要理解中文乱码产生的原因。通常,当...

    JAVA日文字符检查

    根据给定文件的信息,我们可以总结出以下几个主要的知识点: ### 1.... ...- **功能**: 将特殊字符转换为HTML实体...在实际应用中,这些方法通常会被封装成工具类的一部分,并广泛应用于前端表单验证、后端数据校验等场景。

    解乱码,各种乱码之间互相转换

    在IT领域,乱码是一个常见的问题,特别是在处理文本数据时。乱码的出现通常是由于字符编码不匹配或者编码转换不当导致的。字符编码是计算机表示和处理文本的方式,不同的编码方式对应不同的字符集,比如ASCII、GBK、...

Global site tag (gtag.js) - Google Analytics