java基础---->java中字符编码问题(一)

  这里面对java中的字符编码做一个总结,毕竟在项目中会经常遇到这个问题。

文件的编码格式

一、关于中文的二进制字节问题

public static String CHARSET_TEXT = "我爱LL";
// 打印字节的16进制表示
private void printBinarys(byte[] buffer) {
    for (byte b : buffer) {
        System.out.print(Integer.toHexString(b & 0xff) + " ");
    }
    System.out.println();
}
    @Test
public void charset_1() throws Exception {
    /**
     * utf-8是一个中文三个字节,gbk是一个中文两个字节
     */
    printBinarys(CHARSET_TEXT.getBytes()); // e6 88 91 e7 88 b1 4c 4c
    printBinarys(CHARSET_TEXT.getBytes("utf-8")); // e6 88 91 e7 88 b1 4c 4c
    printBinarys(CHARSET_TEXT.getBytes("gbk")); // ce d2 b0 ae 4c 4c
    printBinarys(CHARSET_TEXT.getBytes("iso-8859-1")); // 3f 3f 4c 4c
}

二、字符的编码与解码方式

private void printStringByCharset(byte[] buffer, String charsetName) throws UnsupportedEncodingException {
    System.out.println(new String(buffer, charsetName));
}
@Test
public void charset_2() throws Exception {
    /**
     * 1、CHARSET_TEXT.getBytes("utf-8"):返回的是e6 88 91 e7 88 b1 4c 4c。说明CHARSET_TEXT以utf-8编码成e6 88 91 e7 88 b1 4c 4c
     * 2、new String(buffer, charsetName):对e6 88 91 e7 88 b1 4c 4c以utf-8的方式解码。得到的是CHARSET_TEXT,所以没有乱码。
     * 3、至于iso-8859-1的乱码:
     */
    printStringByCharset(CHARSET_TEXT.getBytes(), "utf-8"); // 我爱LL
    printStringByCharset(CHARSET_TEXT.getBytes("utf-8"), "utf-8"); // 我爱LL
    printStringByCharset(CHARSET_TEXT.getBytes("gbk"), "utf-8"); // ???LL
    printStringByCharset(CHARSET_TEXT.getBytes("iso-8859-1"), "iso-8859-1"); // ??LL
    printStringByCharset(CHARSET_TEXT.getBytes("iso-8859-1"), "utf-8"); // ??LL
}

三、关于文件的编码与读取文件的内容

需要注意的是:文件是以二进制字节的方式存储的。

public static String FILE_PATH = "C:/Users/76801/Desktop/charset/huhx.txt";
public static String FILENAME_PATH = "C:/Users/76801/Desktop/charset/linux.txt";
// 读取文件内容成二进制数组
private void printBinaryFromFile(String filePath, String charsetName) {
    File file = new File(filePath);
    try {
        InputStream stream = new FileInputStream(file);
        byte[] buffers = new byte[stream.available()];
        stream.read(buffers);
        stream.close();
        printStringByCharset(buffers, charsetName);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Test
public void charset_3() throws Exception{
    // 文件的编码是utf-8无DOM
    printBinaryFromFile(FILE_PATH, "UTF-8"); // I love you,中国。
    printBinaryFromFile(FILE_PATH, "GBK"); // I love you,涓浗銆?

    // 转换成gbk2312,编辑器显示的内容:I love you,涓浗銆。但是删除内容,自己重新输入不会出现乱码。这时候,其实是改变了真实的内容。切换编码,并没有改变真实的内容。 
    printStringByCharset("I love you,中国。".getBytes("utf-8"), "gbk"); // I love you,涓浗銆?
    /**
     * 1、一个文件的内容先以utf-8编码写入内容:I love you,L玲。
     * 2、改变它的编码为gbk内容显示:I love you,L鐜层€
     * 3、在下述的测试中,正常显示。据此我们知道,这个文件的保存的二进制是utf-8编码:49 20 6c 6f 76 65 20 79 6f 75 2c 4c e7 8e b2 e3 80 82
     * 4、改变它的编码格式,notepad++并没有改变它本身的二进制内容。只是显示的机制是以gbk对49 20 6c 6f 76 65 20 79 6f 75 2c 4c e7 8e b2 e3 80 82进行解码。
     */
    printBinarys("I love you,L玲。".getBytes("utf-8")); // 49 20 6c 6f 76 65 20 79 6f 75 2c 4c e7 8e b2 e3 80 82
    printStringByCharset("I love you,L玲。".getBytes("utf-8"), "gbk"); // I love you,L鐜层??
    printBinaryFromFile(FILENAME_PATH, "UTF-8"); // I love you,L玲。
}

演示的动态图如下:

三、eclipse中的编码设置影响java的默认编码

此时项目的编码是UTF-8,FirstJava.java文件的编码是ISO-8859-1,SecondJava.java文件的编码是UTF-8。

下面是测试的代码:

public class FirstJava {
    public static void main(String[] args) {
        String charsetName = Charset.defaultCharset().displayName(); // ISO-8859-1
        System.out.println(charsetName);
    }
}

public class SecondJava {
    public static void main(String[] args) {
        String charsetName = Charset.defaultCharset().displayName(); // UTF-8
        System.out.println(charsetName);
    }
}

在FirstJava中,如果文件包含了中文。保存文件的时候会有如下的错误。

友情链接

时间: 2024-08-09 22:01:52

java基础---->java中字符编码问题(一)的相关文章

Java基础----Java中的String和StringBuffer

String和StringBuffer String是一个特殊的对象,一旦被初始化,就不会被改变.()指的是abc 不是变量 s1. String s1="abc"; s1是一个类类型变量,"abc"是一个对象. String s2=new String("abc"); s1和s2的区别: s1在字符串常量池中创建了一个abc字符串 s2在堆中创建了两个对象一个是默认对象一个是字符串对象. ==和equals的区别 ==比较的是地址,equals

Java基础学习中一些词语和语句的使用

在Java基础学习中,我们刚接触Java会遇到一些词和语句的使用不清的情况,不能很清楚的理解它的运行效果会是怎么样的,如:break,continue在程序中运行效果及跳转位置, 1.先来看看break和continue使用和运行效果的额说明: break:关键字,可以用于任何循环体控制结构,在循环体内执行时,当执行到break时循环会立即终止,并跳到此循环体以后的语句执行. 列如:输出0--10的数当输出到第六位时就不在继续输出了,即是跳出for循环执行for循环体以后的一句. public

Java基础----Java API中的常用类

System:描述系统的一些信息 preperties();获取系统信息 Properties prop =new System.getProperties(); 是hashtable 的子类.用map的方法去除该类集合中的元素.该集合中存储的都是字符串,没有泛型定义. String calue=(String)prop.get(obj); System.out.println(obj+":"+value); //如何在系统中自定义一些特有信息? System.setProperty(

java统计字符串中字符及子字符串个数

import java.util.Scanner;public class Counter { static Scanner scanner = new Scanner(System.in); public static void count(String s) { int low, upper, num, others; low = upper = num = others = 0; for (int i = 0; i < s.length(); i++) { if (Character.is

java基础----&gt;java中正则表达式二

跟正则表达式相关的类有:Pattern.Matcher和String.今天我们就开始Java中正则表达式的学习. Pattern和Matcher的理解 一.正则表达式的使用方法 一般推荐使用的方式如下: Pattern pattern = Pattern.compile("^[^abc]h$"); Matcher matcher = pattern.matcher("hh"); boolean isMatch = matcher.matches(); 另外一种不能复

Java基础--Java入门

IsCoder 标记: Java基础,Java环境配置 一.Java环境配置 Java Develop Kit(JDK安装) 系统环境变量设置(JAVA_HOME) Java源程序编辑工具 Java编译运行命令 运行经典的HelloWorld程序 1.1 JDK安装 JDK,就是甲骨文公司提供给我们的Java开发工具包,包括最常用的Javac.exe编译工具和Java.exe运行工具.需要指出的是,JDK中已经包含了JER(Java Runtime Environment,Java运行时环境),

Java基础--Java编程规范

IsCoder 标记: Java基础,Java编程规范 摘要:Java虽然没有强制性的编程规范,但是为了便于统一,Java有不成文的编程规范,为了形成良好的编程习惯,建议熟悉并遵守Java编程规范,提高代码的阅读性. 一.Java标识符 在任何语言中,都要自己的一套标识符规则.Java的标识符包括:Java关键字.Java特殊功能的标识符.合法的用户自定义标识符.其中,我们能改变的只有自定义的标识符,和大部分计算机编程语言一样,Java标识符原始只支持ASCII的编码,但是随着Java在世界的影

[Java基础] Java对象内存结构

转载地址:http://www.importnew.com/1305.html 原文于2008年11月13日 发表, 2008年12月18日更新:这里还有一篇关于Java的Sizeof运算符的实用库的文章. 学C/C++出身的我,对Java有一点非常困惑,那就是缺乏计算对象占用内存大小的机制.而在C++中就可以通过sizeof运算符来获得基本类型以及类实例的大小.C和C++中的这个操作符对于指针运算.内存拷贝和IO操作都非常有用. Java中并没有一个类似的运算符.事实上,Java也不需要这种运

程序猿二三事之Java基础--Java SE 5增加的特性--语法篇(一)

程序猿二三事之Java基础–Java SE 5增加的特性–语法篇(一) [ TOC ] 为什么是Java SE 5? 目前已经到了JDK-8u74了,JDK7的主版本已经于2015年4月停止公开更新. 那为什么还要来说Java/JDK5呢? Java SE在1.4(2002)趋于成熟,随着越来越多应用于开发企业应用,许多框架诞生于这个时期或走向成熟. Java SE 5.0的发布(2004)在语法层面增加了很多特性,让开发更高效,代码更整洁. 自动装箱/拆箱.泛型.注解.for循环增强.枚举.可

[Java基础] Java线程复习笔记

先说说线程和进程,现代操作系统几乎无一例外地采用进程的概念,进程之间基本上可以认为是相互独立的,共享的资源非常少.线程可以认为是轻量级的进 程,充分地利用线程可以使得同一个进程中执行多种任务.Java是第一个在语言层面就支持线程操作的主流编程语言.和进程类似,线程也是各自独立的,有自 己的栈,自己的局部变量,自己的程序执行并行路径,但线程的独立性又没有进程那么强,它们共享内存,文件资源,以及其他进程层面的状态等.同一个进程内的 多个线程共享同样的内存空间,这也就意味着这些线程可以访问同样的变量和