`

【Java基础专题】编码与乱码(02)---String的getBytes([encoding])方法

 
阅读更多
package example.encoding;

import java.io.UnsupportedEncodingException;

/** *//**
 * The Class GetBytesTest.
 */
public class GetBytesTest {

    /** *//**
     * The main method.
     * 
     * @param args the arguments
     */
    public static void main(String args[]) {
        
        String content = "中文";
        String defaultEncoding = System.getProperty("file.encoding");
        String defaultLnaguage = System.getProperty("user.language");
        System.out.println("System default encoding --- " + defaultEncoding);
        System.out.println("System default language --- " + defaultLnaguage);

        GetBytesTest tester = new GetBytesTest();

        byte[] defaultBytes = tester.getBytesWithDefaultEncoding(content);
        tester.printBytes(defaultBytes);

        byte[] iso8859Bytes = tester.getBytesWithGivenEncoding(content,
                "ISO-8859-1");
        tester.printBytes(iso8859Bytes);

        byte[] gbkBytes = tester.getBytesWithGivenEncoding(content, "GBK");
        tester.printBytes(gbkBytes);

        byte[] utfBytes = tester.getBytesWithGivenEncoding(content, "UTF-8");
        tester.printBytes(utfBytes);

    }

    /** *//**
     * Gets the bytes with default encoding.
     * 
     * @param content the content
     * 
     * @return the bytes with default encoding
     */
    public byte[] getBytesWithDefaultEncoding(String content) {
        System.out.println("\nEncode with default encoding\n");
        byte[] bytes = content.getBytes();
        return bytes;
    }

    /** *//**
     * Gets the bytes with given encoding.
     * 
     * @param content the content
     * @param encoding the encoding
     * 
     * @return the bytes with given encoding
     */
    public byte[] getBytesWithGivenEncoding(String content, String encoding) {
        System.out.println("\nEncode with given encoding : " + encoding + "\n");
        try {
            byte[] bytes = content.getBytes(encoding);
            return bytes;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    /** *//**
     * Prints the bytes.
     * 
     * @param bytes the bytes
     */
    public void printBytes(byte[] bytes) {
        for (int i = 0; i < bytes.length; i++) {
            System.out.print(" byte[" + i + "] = " + bytes[i]);
            System.out
                    .println(" hex string = " + Integer.toHexString(bytes[i]));
        }
    }

}

 【1】在中文平台下,测试结果如下:


System default encoding --- GBK
System default language --- zh

Encode with default encoding

 byte[0] = -42 hex string = ffffffd6
 byte[1] = -48 hex string = ffffffd0
 byte[2] = -50 hex string = ffffffce
 byte[3] = -60 hex string = ffffffc4

Encode with given encoding : ISO-8859-1

 byte[0] = 63 hex string = 3f
 byte[1] = 63 hex string = 3f

Encode with given encoding : GBK

 byte[0] = -42 hex string = ffffffd6
 byte[1] = -48 hex string = ffffffd0
 byte[2] = -50 hex string = ffffffce
 byte[3] = -60 hex string = ffffffc4

Encode with given encoding : UTF-8

 byte[0] = -28 hex string = ffffffe4
 byte[1] = -72 hex string = ffffffb8
 byte[2] = -83 hex string = ffffffad
 byte[3] = -26 hex string = ffffffe6
 byte[4] = -106 hex string = ffffff96
 byte[5] = -121 hex string = ffffff87

【2】在英文平台下,测试结果如下:


System default encoding --- Cp1252
System default language --- en

 

Encode with default encoding

 byte[0] = 63 hex string = 3f
 byte[1] = 63 hex string = 3f

Encode with given encoding : ISO-8859-1

 byte[0] = 63 hex string = 3f
 byte[1] = 63 hex string = 3f

Encode with given encoding : GBK

 byte[0] = -42 hex string = ffffffd6
 byte[1] = -48 hex string = ffffffd0
 byte[2] = -50 hex string = ffffffce
 byte[3] = -60 hex string = ffffffc4

Encode with given encoding : UTF-8

 byte[0] = -28 hex string = ffffffe4
 byte[1] = -72 hex string = ffffffb8
 byte[2] = -83 hex string = ffffffad
 byte[3] = -26 hex string = ffffffe6
 byte[4] = -106 hex string = ffffff96
 byte[5] = -121 hex string = ffffff87

【结论】


getBytes()、getBytes(encoding)函数的作用是使用系统默认或者指定的字符集编码方式,将字符串编码成字节数组。

 

在中文平台下,默认的字符集编码是GBK,此时如果使用getBytes()或者getBytes("GBK"),则按照GBK的编码规则将每个中文字符用2个byte表示。所以我们看到"中文"最终GBK编码结果就是: -42 -48 -50 -60 。-42和-48代表了"中"字,而"-50"和"-60"则代表了"文"字。

在中文平台下,如果指定的字符集编码是UTF-8,那么按照UTF-8对中文的编码规则:每个中文用3个字节表示,那么"中文"这两个字符最终被编码成:-28 -72 -83、-26 -106 -121两组。每3个字节代表一个中文字符。

在中文平台下,如果指定的字符集编码是ISO-8859-1,由于此字符集是单字节编码,所以使用getBytes("ISO-8859-1")时,每个字符只取一个字节,每个汉字只取到了一半的字符。另外一半的字节丢失了。由于这一半的字符在字符集中找不到对应的字符,所以默认使用编码63代替,也就是?。

在英文平台下,默认的字符集编码是Cp1252(类似于ISO-8859-1),如果使用GBK、UTF-8进行编码,得到的字节数组依然是正确的(GBK4个字节,UTF-8是6个字节)。因为在JVM内部是以Unicode存储字符串的,使用getBytes(encoding)会让JVM进行一次Unicode到指定编码之间的转换。对于GBK,JVM依然会转换成4个字节,对于UTF-8,JVM依然会转换成6个字节。但是对于ISO-8859-1,则由于无法转换(2个字节--->1个字节,截取了一半的字节),所以转换后的结果是错误的。

相同的平台下,同一个中文字符,在不同的编码方式下,得到的是完全不同的字节数组。这些字节数组有可能是正确的(只要该字符集支持中文),也可能是完全错误的(该字符集不支持中文)。

记住:

不要轻易地使用或滥用String类的getBytes(encoding)方法,更要尽量避免使用getBytes()方法。因为这个方法是平台依赖的,在平台不可预知的情况下完全可能得到不同的结果。如果一定要进行字节编码,则用户要确保encoding的方法就是当初字符串输入时的encoding。

 

分享到:
评论

相关推荐

    java 编码 UTF-8、ISO-8859-1、GBK

    例如,如果数据库是UTF-8,JSP是GBK,可以使用 `new String(rs.getBytes(1),"UTF-8")` 将数据库中的UTF-8字节流转换为GBK字符串。反之,如果JSP是UTF-8,数据库是GBK,需要先将GBK字符串转换为字节流,然后再次转换...

    Java中压缩与解压--中文文件名乱码解决办法

    尤其是在Windows系统下,文件名通常采用GB2312或GBK编码,而Java中的`ZipInputStream`和`ZipOutputStream`类默认使用的是Unicode编码,这种编码差异导致了中文文件名在压缩与解压过程中的乱码现象。 #### 二、解决...

    关于java中的编码转换问题(解决乱码问题)

    在Java中,String类提供了`getBytes()`方法,用于将字符串转换为字节数组,使用默认的平台编码。若需指定编码,可使用`getBytes(String charsetName)`,如`getBytes("UTF-8")`。 三、文件编码转换 Java的`...

    java乱码问题解决方法

    Java 乱码问题是 Java 开发中常见的问题之一,解决这个问题需要了解 Java 的编码方式、JSP 中文乱码问题、Tomcat 5.5 中文乱码问题、JDBC ODBC Bridge 的 Bug 及其解决方法、Solaris 下 Servlet 编程的中文问题及...

    C#(.net)中按字节数截取字符串最后出现乱码问题的解决

    前言 最近需要用到按字节数截取字符串。在网上找了很多方法。... string msg= Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(strcode)); 例子:2 string strcode=我是小明; byte[] buffer=Encoding.UTF8.Ge

    Java设置String字符串编码方法详解

    本文将深入探讨Java中设置String字符串编码的方法,帮助开发者更好地理解和使用这些功能。 首先,我们需要理解什么是字符编码。字符编码是将字符(如字母、数字和符号)与数字或二进制值关联的系统,例如ASCII、...

    java中文乱码解决问题

    这是因为在编译 Servlet 类或者 JSP 文件时,如果没有使用 -encoding 参数指定 Java 源程序的编码格式,javac 会获取本地操作系统默认采用的字符集,以该字符集将 Java 源程序转换为 Unicode 编码保存到内存中,然后...

    java 中文乱码 处理

    以上介绍了几种常见的Java中文乱码处理方法,包括请求参数编码转换、字符串转义与反转义、前端JavaScript处理以及配置J2EE应用程序。每种方法都有其适用场景,开发者可以根据实际情况选择合适的方法来解决乱码问题。...

    解析Java中文乱码的处理方法

    Java编程语言在处理中文字符时,可能会遇到乱码问题,这通常是由于编码设置不正确或者在数据读写过程中没有统一编码格式导致的。本篇文章将深入探讨Java中处理中文乱码的各种方法,帮助开发者有效解决这类问题。 ...

    Java乱码问题解决

    ### Java乱码问题详解与解决方案 #### 一、问题背景 在Java开发过程中,尤其是在处理中文字符时,经常遇到字符编码不一致导致的乱码问题。由于Java默认使用Unicode编码,而在中国大陆地区,常见的字符集为GB2312...

    java Socket与C#通信中中文乱码问题的解决方案

    在Java和C#之间进行Socket通信时,遇到中文乱码问题主要是由于编码格式不一致导致的。Java默认使用UTF-8编码,而C#在处理字符串时可能使用其他编码,如GBK或ASCII。为了解决这个问题,我们需要确保两端在发送和接收...

    详解Java中String类型与默认字符编码

    Java中String类型与默认字符编码详解 Java中String类型与默认字符编码是Java编程语言中一个重要的概念。String类型是Java中最基本的数据类型之一,它用于表示文本数据。然而,在Java中String类型的默认编码方式一直...

    java乱码自己解决的办法

    在Java开发过程中,字符编码问题常常困扰着开发者,尤其是在处理中文等多字节字符时,乱码问题尤为突出。本文将深入探讨Java乱码的根源,并提供一系列实用的解决方案,帮助开发者有效应对这一挑战。 ### Java乱码...

    java解决中文乱码问题

    `String s2 = new String(s1.getBytes("ISO-8859-1"), "GBK");` 3. 使用 Tomcat 的 CharacterEncodingFilter Tomcat 5.5 中文乱码的问题可以使用 CharacterEncodingFilter 来解决。首先,需要将 %TOMCAT 安装目录%...

    用java修改文件的编码

    - 将读取到的每一行转换为目标编码,可以使用`String`的`getBytes()`和`new String()`方法。 - 使用`BufferedWriter`的`write()`方法将转换后的字符串写入新文件。 - 不要忘记关闭所有打开的流。 5. **示例代码*...

    JAVA 转换字符编码工具

    - `EncodingConverter.java`:这个类最直接地与字符编码转换相关,它可能提供了从一种编码转换到另一种编码的方法。 5. **实际应用** - 在处理不同编码的文件或网络数据时,如XML、JSON或纯文本文件,可能需要...

    java字符编码错误整理大全

    当需要将字符串从一种编码转换为另一种编码时,可以使用`getBytes()`和`new String()`方法来实现。 ```java byte[] byteArray = text.getBytes("ISO-8859-1"); String convertedText = new String(byteArray, ...

    java多种解决乱码方案详细资料大全

    - `getBytes()`和`new String()`操作可能导致乱码,需指定正确的编码。如:`new String(bytes, "UTF-8")`。 5. JDBC连接编码: - 在JDBC连接字符串中指定数据库的编码,例如:`jdbc:mysql://localhost:3306/test?...

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

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

Global site tag (gtag.js) - Google Analytics