`

Java字符编码相关

    博客分类:
  • java
阅读更多

JVM启动后,JVM会设置一些系统属性以表明JVM的缺省区域。user.language,user.region,file.encoding等。 可以使用System.getProperties()详细查看所有的系统属性。

 

如在英文操作系统(UNIX)下,可以使用如下属性定义强制指定JVM为中文环境 -Dclient.encoding.override=GBK -Dfile.encoding=GBK -Duser.language=zh -Duser.region=CN

 

.java-->.class编译

说明:一般javac根据当前os区域设置,自动决定源文件的编码.可以通过-encoding强制指定.

 

错误可能:

1 gbk编码源文件在英文环境下编译,javac不能正确转换.曾见于java/jsp在英文unix. 检测方法:\u4e00格式的汉字,绕开javac编码,再在jvm,将汉字作为int打印,看值是否相等;或直接以UTF-8编码打开.class文件,看看常量字符串是否正确保存汉字。

 

文件读写

外部数据如文件经过读写和转换两个步骤,转为jvm所使用字符。InputStream/OutputStream用于读写原始外部数据,Reader/Writer执行读写和转换两个步骤。

 

1 文件读写转换由java.io.Reader/Writer执行;输入输出流 InputStream/OutputStream 处理汉字不合适,应该首选使用Reader/Writer,如 FileReader/FileWriter

 

2 FileReader/FileWriter使用JVM当前编码读写文件.如果有其它编码格式,使用InputStreamReader/OutputStreamWriter

 

3 PrintStream有点特殊,它自动使用jvm缺省编码进行转换。

 

 

读取.properties文件

.propeties文件由Properties类以iso8859-1编码读取,因此不能在其中直接写汉字,需要使用JDK native2ascii工具转换汉字为\uXXXX格式。命令行:native2ascii –encoding GBK inputfile outputfile

 

读取XML文件

1 XML文件读写同于文件读写,但应注意确保XML头中声明如<? xml version=”1.0” encoding=”gb2312” ?>与文件编码保持一致。

 

2 javax.xml.SAXParser类接受InputStream作为输入参数,对于Reader,需要用org.xml.sax.InputSource包装一下,再给SAXParser

 

3 对于UTF-8编码 XML,注意防止编辑器自动加上\uFFFE BOM, xml parser会报告content is not allowed in prolog

 

 

字节数组

1 使用 new String(byteArray,encoding) String.getBytes(encoding) 在字节数组和字符串之间进行转换

 

也可以用ByteArrayInputStream/ByteArrayOutputStream转为流后再用InputStreamReader/OutputStreamWriter转换。

 

错误编码的字符串(iso8859-1转码gbk)

如果我们得到的字符串是由错误的转码方式产生的,例如:对于gbk中文,由iso8859-1方式转换,此时如果用调试器看到的字符串一般是 的样子,长度一般为文本的字节长度,而非汉字个数。

 

可以采用如下方式转为正确的中文:

text = new String( text.getBytes(“iso8859-1”),”gbk”);

 

JDBC

转换过程由JDBC Driver执行,取决于各JDBC数据库实现。对此经验尚积累不够。

 

1 对于ORACLE数据库,需要数据库创建时指定编码方式为gbk,否则会出现汉字转码错误

2 对于 SQL Server 2000 ,最好以nvarchar/nchar类型存放文本,即不存在中文/编码转换问题。

3 连接 Mysql,将 connectionString 设置成 encoding gb2312

String connectionString = "jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=gb2312";

 

WEB/Servlet/JSP

1 对于JSP,确定头部加上 <%@ page contentType="text/html;charset=gb2312"%>这样的标签。

2 对于Servlet,确定 设置setContentType (“text/html; charset=gb2312”),以上两条用于使得输出汉字没有问题。

3 为输出HTML head中加一个 <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> ,让浏览器正确确定HTML编码。

 

4 Web应用加一个Filter,确保每个Request明确调用setCharacterEncoding方法,让输入汉字能够正确解析。

 

——————————————————————————————————————

 

import java.io.UnsupportedEncodingException;

/**
* 转换字符串的编码
*/
public class ChangeCharset {
/** 7位ASCII字符,也叫作ISO646-US、Unicode字符集的基本拉丁块 */
public static final String US_ASCII = "US-ASCII";

/** ISO 拉丁字母表 No.1,也叫作 ISO-LATIN-1 */
public static final String ISO_8859_1 = "ISO-8859-1";

/** 8 位 UCS 转换格式 */
public static final String UTF_8 = "UTF-8";

/** 16 位 UCS 转换格式,Big Endian(最低地址存放高位字节)字节顺序 */
public static final String UTF_16BE = "UTF-16BE";

/** 16 位 UCS 转换格式,Little-endian(最高地址存放低位字节)字节顺序 */
public static final String UTF_16LE = "UTF-16LE";

/** 16 位 UCS 转换格式,字节顺序由可选的字节顺序标记来标识 */
public static final String UTF_16 = "UTF-16";

/** 中文超大字符集 */
public static final String GBK = "GBK";

/**
* 将字符编码转换成US-ASCII码
*/
public String toASCII(String str) throws UnsupportedEncodingException{
   return this.changeCharset(str, US_ASCII);
}
/**
* 将字符编码转换成ISO-8859-1码
*/
public String toISO_8859_1(String str) throws UnsupportedEncodingException{
   return this.changeCharset(str, ISO_8859_1);
}
/**
* 将字符编码转换成UTF-8码
*/
public String toUTF_8(String str) throws UnsupportedEncodingException{
   return this.changeCharset(str, UTF_8);
}
/**
* 将字符编码转换成UTF-16BE码
*/
public String toUTF_16BE(String str) throws UnsupportedEncodingException{
   return this.changeCharset(str, UTF_16BE);
}
/**
* 将字符编码转换成UTF-16LE码
*/
public String toUTF_16LE(String str) throws UnsupportedEncodingException{
   return this.changeCharset(str, UTF_16LE);
}
/**
* 将字符编码转换成UTF-16码
*/
public String toUTF_16(String str) throws UnsupportedEncodingException{
   return this.changeCharset(str, UTF_16);
}
/**
* 将字符编码转换成GBK码
*/
public String toGBK(String str) throws UnsupportedEncodingException{
   return this.changeCharset(str, GBK);
}

/**
* 字符串编码转换的实现方法
* @param str   待转换编码的字符串
* @param newCharset 目标编码
* @return
* @throws UnsupportedEncodingException
*/
public String changeCharset(String str, String newCharset)
    throws UnsupportedEncodingException {
   if (str != null) {
    //用默认字符编码解码字符串。
    byte[] bs = str.getBytes();
    //用新的字符编码生成字符串
    return new String(bs, newCharset);
   }
   return null;
}
/**
* 字符串编码转换的实现方法
* @param str   待转换编码的字符串
* @param oldCharset 原编码
* @param newCharset 目标编码
* @return
* @throws UnsupportedEncodingException
*/
public String changeCharset(String str, String oldCharset, String newCharset)
    throws UnsupportedEncodingException {
   if (str != null) {
    //用旧的字符编码解码字符串。解码可能会出现异常。
    byte[] bs = str.getBytes(oldCharset);
    //用新的字符编码生成字符串
    return new String(bs, newCharset);
   }
   return null;
}

public static void main(String[] args) throws UnsupportedEncodingException {
   ChangeCharset test = new ChangeCharset();
   String str = "This is a 中文的 String!";
   System.out.println("str: " + str);
   String gbk = test.toGBK(str);
   System.out.println("转换成GBK码: " + gbk);
   System.out.println();
   String ascii = test.toASCII(str);
   System.out.println("转换成US-ASCII码: " + ascii);
   gbk = test.changeCharset(ascii,ChangeCharset.US_ASCII, ChangeCharset.GBK);
   System.out.println("再把ASCII码的字符串转换成GBK码: " + gbk);
   System.out.println();
   String iso88591 = test.toISO_8859_1(str);
   System.out.println("转换成ISO-8859-1码: " + iso88591);
   gbk = test.changeCharset(iso88591,ChangeCharset.ISO_8859_1, ChangeCharset.GBK);
   System.out.println("再把ISO-8859-1码的字符串转换成GBK码: " + gbk);
   System.out.println();
   String utf8 = test.toUTF_8(str);
   System.out.println("转换成UTF-8码: " + utf8);
   gbk = test.changeCharset(utf8,ChangeCharset.UTF_8, ChangeCharset.GBK);
   System.out.println("再把UTF-8码的字符串转换成GBK码: " + gbk);
   System.out.println();
   String utf16be = test.toUTF_16BE(str);
   System.out.println("转换成UTF-16BE码:" + utf16be);
   gbk = test.changeCharset(utf16be,ChangeCharset.UTF_16BE, ChangeCharset.GBK);
   System.out.println("再把UTF-16BE码的字符串转换成GBK码: " + gbk);
   System.out.println();
   String utf16le = test.toUTF_16LE(str);
   System.out.println("转换成UTF-16LE码:" + utf16le);
   gbk = test.changeCharset(utf16le,ChangeCharset.UTF_16LE, ChangeCharset.GBK);
   System.out.println("再把UTF-16LE码的字符串转换成GBK码: " + gbk);
   System.out.println();
   String utf16 = test.toUTF_16(str);
   System.out.println("转换成UTF-16码:" + utf16);
   gbk = test.changeCharset(utf16,ChangeCharset.UTF_16LE, ChangeCharset.GBK);
   System.out.println("再把UTF-16码的字符串转换成GBK码: " + gbk);
   String s = new String("中文".getBytes("UTF-8"),"UTF-8");
   System.out.println(s);
}
}

------------------------------------------------------------------------------------------------------------------


        java中的String类是按照unicode进行编码的,当使用String(byte[] bytes, String encoding)构造字符串时,encoding所指的是bytes中的数据是按照那种方式编码的,而不是最后产生的String是什么编码方式,换句 话说,是让系统把bytes中的数据由encoding编码方式转换成unicode编码。如果不指明,bytes的编码方式将由jdk根据操作系统决 定。

        当我们从文件中读数据时,最好使用InputStream方式,然后采用String(byte[] bytes, String encoding)指明文件的编码方式。不要使用Reader方式,因为Reader方式会自动根据jdk指明的编码方式把文件内容转换成unicode 编码。

        当我们从数据库中读文本数据时,采用ResultSet.getBytes()方法取得字节数组,同样采用带编码方式的字符串构造方法即可。

ResultSet rs;
bytep[] bytes = rs.getBytes();
String str = new String(bytes, "gb2312");

不要采取下面的步骤。

ResultSet rs;
String str = rs.getString();
str = new String(str.getBytes("iso8859-1"), "gb2312");

        这种编码转换方式效率底。之所以这么做的原因是,ResultSet在getString()方法执行时,默认数据库里的数据编码方式为 iso8859-1。系统会把数据依照iso8859-1的编码方式转换成unicode。使用str.getBytes("iso8859-1")把数 据还原,然后利用new String(bytes, "gb2312")把数据从gb2312转换成unicode,中间多了好多步骤。

        从HttpRequest中读参数时,利用reqeust.setCharacterEncoding()方法设置编码方式,读出的内容就是正确的了。

顺便说句,如果你直接在浏览器中的地址栏输入这个的话,浏览器都会使用ISO-8859-1来编码你的URL,然后才提交到服务器
分享到:
评论

相关推荐

    java字符串的各种编码转换

    ### Java字符串的编码转换 在Java中,处理不同字符集之间的字符串转换是一项常见任务。尤其是在处理国际化应用时,理解并掌握各种字符编码格式变得尤为重要。下面将介绍几种常见的字符编码格式以及如何在Java中实现...

    java字符编码监听器

    Java字符编码监听器是Java Web开发中的一个重要概念,主要用于处理HTTP请求和响应中的字符编码问题。在Java Servlet规范中,提供了`SetCharacterEncodingFilter`这样的过滤器,用于确保请求参数和响应内容的正确编码...

    Java字符集编码简记

    本文将围绕“Java字符集编码简记”这一主题,深入探讨相关知识点,并结合标签“源码”和“工具”,探讨在实际开发中如何运用和处理字符编码问题。 首先,我们需要理解字符集的概念。字符集是一系列符号的集合,例如...

    java_字符编码 Javajava_字符编码问题

    ### Java 字符编码详解 #### 一、Java 字符编码基础概念 在深入探讨 Java 字符编码的问题之前,我们先来了解一下字符编码的基本概念。字符编码是计算机内部表示字符的一种方式,它涉及到如何将人类可读的文字转换...

    Java字符集和编码

    UTF-8(Unicode Transformation Format-8)是一种可变长度的字符编码格式,主要用于在网络中快速传输Unicode字符。UTF-8的基本原理是根据Unicode字符的范围,将其映射成不同长度的编码,具体规则如下: - 每个英文...

    JAVA_字符编码

    此外,Java的`String`类提供了许多与字符编码相关的功能,如`getBytes()`方法可以将字符串转换为字节数组,使用默认的平台字符集,或者指定的`Charset`。而`new String(bytes, charset)`则可以根据给定的字节数组和...

    JAVA 转换字符编码工具

    在Java中,每个字符串都有一个默认的字符编码,通常是平台相关的(例如,Windows系统通常默认使用GBK,而Linux系统则可能是UTF-8)。 Java提供了`java.nio.charset`包来处理字符编码。其中,`Charset`类是核心,它...

    java字符编码问题

    ### Java字符编码问题详解 #### 一、引言 在Java开发过程中,字符编码问题是一个常见且容易引发各种隐藏问题的领域。不正确的字符编码处理可能...希望本文能帮助读者更好地理解Java字符编码的相关概念和技术细节。

    Java中的字符集编码入门(五)Java代码中的字符编码转换Part1.pdf

    Java中的字符编码转换是编程实践中一个至关重要的概念,尤其是在处理多语言环境和跨平台交互时。Java通过统一采用UTF-16编码格式在JVM内部处理字符,简化了字符操作的复杂性。UTF-16是一种变长的Unicode编码,它可以...

    java字符串编码转换

    ### Java字符串编码转换详解 #### 一、Java 字符串编码转换基础 在Java中,字符串的处理是非常常见的操作之一,而字符编码是确保数据正确显示的关键因素。本篇文章将重点介绍Java中字符串编码的转换方法及其在Web...

    java字符编码错误整理大全

    ### Java字符编码错误整理大全 #### 一、概述 在Java开发过程中,字符编码问题是非常常见且容易引发一系列乱码问题的重要因素。本篇将详细梳理Java中的字符编码相关知识点,帮助开发者解决实际工作中遇到的各种...

    Java字符编码及获取文件编码

    在Java编程语言中,字符编码是一个至关重要的概念,它涉及到数据的存储、处理和传输。...通过本文介绍的知识,你应该能够更好地应对编码相关的挑战,并且可以进一步研究`FIleCode.java`源代码,加深理解。

    java文件字符编码检测和转换

    字符编码检测和转换 附件中:FileEncodeDetector.java 此文件可以检测指定文件的编码格式 public static String getFileEncode(File file) {...} 附件中:FileCharsetConverter.java 此文件可以实现两个编码的相互...

    JAVA字符编码系列三[借鉴].pdf

    Java字符编码系列三主要探讨了Java应用中遇到的编码问题,包括编码基础知识、Java与系统软件、URL、工具软件等方面的处理。文章通过“中文”二字举例,解释了不同编码方式如GB2312、Unicode、UTF-8的表示方法。 1. ...

    Java字符编码简介_动力节点Java学院整理

    Java字符编码是编程中至关重要的一个概念,尤其是在处理多语言数据时。本文主要探讨了Java中与字符编码相关的基础知识,包括ISO8859-1、GB2312、GBK、Unicode以及UTF编码。 首先,ISO8859-1是一种早期的单字节编码...

    java文件字符编码集判断依赖.zip

    通用的文件字符编码集判断需要借助第三方包cpdetector.jar 使用Cpdetector jar包检测文件编码需要依赖antlr-2.7.7.jar、chardet-1.0.jar、jargs-1.0.jar三个jar包 本下载资源一站式全包含,并附带亲测有效的片段...

    java字符编码转换详细过程

    ### Java字符编码转换详细过程 #### 一、Java程序的生命周期与字符编码处理流程 Java程序的生命周期可以概括为三个主要阶段:编写源代码、编译源代码以及运行编译后的类文件。在这个过程中,涉及到多种字符编码的...

    java字符集编码问题

    ### Java字符集编码问题详解 #### 一、引言 在Java编程中,字符集编码问题是一个常见且重要的议题。由于不同的系统、平台以及网络环境中可能存在多种字符编码格式,这导致了在处理文本数据时可能会遇到编码不一致...

    关于JAVA字符编码:Unicode,ISO-8859-1,GBK,UTF-8编码及相互转换

    ### 关于JAVA字符编码:Unicode, ISO-8859-1, GBK, UTF-8 编码及相互转换 在Java开发过程中,字符编码是处理文本数据的基础,不同的编码方式会影响数据的存储、传输以及显示。本文将详细介绍几种常见的字符编码...

Global site tag (gtag.js) - Google Analytics