字符集:
ASCII:American Standard Code for Information Interchange,美国信息互换标准代码
一个字节,其编码范围是0x00-0x7F,共128个字符。
最高位为0,低 7 位表示128个字符,包括大小写字母、数字0-9、标点符号、非打印字符(换行符、制表符等4个)以及控制字符(退格、响铃等)组成。
ISO-8859-1(扩展字符集):对ASCII扩展,主要支持欧洲使用的语言。
一个字节,向下兼容ASCII,其编码范围是0x00-0xFF,共256个字符。
0x00-0x7F之间完全和ASCII一致,0x80-0xFF之间是扩展部分。
GB2312:信息交换用汉字编码字符集, ASCII 的中文扩展,用于中文编码。
汉字占用二个字节,字母数字占一个字节,是为了兼容ASCII(中国人也需要字母和数字)
由于ASCII最高位为0,因此GB2312 规定汉字的两个字节的最高位都是1。
第一个字节(高字节)从0xA1用到 0xF7,第二个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了,ASCII 里本来就有的数字、标点、字母也都编了两个字节长的编码,这就是常说的”全角”字符,而原来在ASCII码就叫”半角”字符了


文件长度为3个字节,前二位为中文汉字,最后一个字节为字母A。
GBK: 汉字内码扩展规范
由于GB2312编码不够用,所以出现GBK编码。GBK编码是GB2312的扩展,是向上兼容的,因此GB2312中的汉字的编码与GBK中汉字的相同。
汉字占用二个字节,字母数字占一个字节,是为了兼容ASCII(中国人也需要字母和数字)
第一个字节(高字节)从0x81用到 0xFE,第二个字节(低字节)从0x40到0xFE(不再要求低字节最高位为1),这样能表示更多的汉字,共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。
ASNI编码:
不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、Big5、Shift_JIS 等各自的编码标准。这些使用 1 至 4 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码;在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码。


unicode:
”Universal Multiple-Octet Coded Character Set”,简称 UCS
Unicode也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。
Unicode用数字0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个码位。
Unicode只是一个符号集,相当于字典,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。
Unicode 兼容ASCII码,前128个字符与ASCII相同。
UCS-2 unicode的第一版本,用2个字节表示所有语言文字符号,取值范围为 U+0000~U+FFFF。
UCS-4 unicode的第二版本,用4个字节表示所有语言文字符号,它的范围为 U+00000000~U+7FFFFFFF,其中 U+00000000~U+0000FFFF和UCS-2是一样的
UCS-4, UCS-2 和 ASCII是向下兼容的,只要前面补0就可以了。
Big Endian和Little Endian
一个字符编码占多个字节,有高字节和低字节,怎样的排列顺序?
Big Endian:规定高字节在前
Little Endian:规定低字节在前。
BOM:
BOM是指字节序标志(Byte Order Mark),是为了区分big还是little字节序的,通常在UTF格式文件头位置。
EF BB BF UTF-8
FE FF UTF-16/UCS-2, big endian
FF FE UTF-16/UCS-2, little endian
FF FE 00 00 UTF-32/UCS-4, little endian.
00 00 FE FF UTF-32/UCS-4, big-endian.
不带BOM头的UTF文件,默认为 little endian。
UTF-16 :UCS Transfer Format 16
UTF-16 用两个字节来表示 Unicode 转化格式,对应UCS-2。UTF-16 表示字符非常方便,每两个字节表示一个字符,这个在字符串操作时就大大简化了操作,这也是 Java 以 UTF-16 作为内存的字符存储格式的一个很重要的原因。
UTF-16需要在文件头上识别字节排列顺序(BOM)。
UTF-32 :UCS Transfer Format 32
UTF-32 用四个字节来表示 Unicode 转化格式,对应UCS-4。
UTF-32需要在文件头上识别字节排列顺序(BOM)。
UTF-8: UCS Transfer Format 8
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,UTF-8用1到6个字节编码UNICODE字符。
UTF-16和UTF-32表示ASCII,会浪费很多字节,只有一个字节表示符号其它字节都为0x00。
UTF-8编码规则:
1)前128个字符,一个字节表示:最高位为0,低七位编码表示128个字符----》与ASCII编码相同。相比UTF-16,UTF-32节省了很多空间。
2)其它字符,用多字节表示,第一个字节高位开始,有几个1就表示该字符由几个字节组成,之后的每个字节的高二位均为10,除了以上控制位,其余位表示UNICODE码。
Unicode/UCS-4
|
bit数
|
UTF-8
|
byte数
|
备注
|
0000 ~
007F
|
0~7
|
0XXX XXXX
|
1
|
|
0080 ~
07FF
|
8~11
|
110X XXXX
10XX XXXX
|
2
|
|
0800 ~
FFFF
|
12~16
|
1110XXXX
10XX XXXX
10XX XXXX
|
3
|
基本定义范围:0~FFFF
|
1 0000 ~
1F FFFF
|
17~21
|
1111 0XXX
10XX XXXX
10XX XXXX
10XX XXXX
|
4
|
Unicode6.1定义范围:0~10 FFFF
|
java 内部使用UTF-16表示字符char,字符串String ,StringBuilder:
System.out.println(System.getProperty("file.encoding"));
char asciiA ='A';
System.out.format("A.hex=%x", (short) asciiA);//显示41,自动把第一个字节的0去掉了。
System.out.println();
char zhong = '中';
System.out.format("中.hex=%x", (short) zhong);//对第二个参数(短整型)格式化为十六进制输出,0x开头 //输出4e2d
System.out.println();
char zhong1 = 0x4e2d;//unicode代码数值表示"中"
System.out.println("0x4e2d=" + zhong);
String zhong2 = "\u4e2d";//unicode代码字符串表示
System.out.println("\\u4e2d=" + zhong);//输出"中"
FileOutputStream fos = new FileOutputStream("charset.txt");
fos.write(zhong>>8);
fos.write(zhong);//用字节流输出"中"字的编码,文件中显示:4E 2A
fos.write(asciiA>>8);
fos.write(asciiA); //用字节流输出"A"字的编码,文件中显示:00 41
fos.close();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("charset1.txt"),"UTF-16"));
bw.write(zhong);
bw.write(asciiA);
bw.close();
输出结果:
GBK
A.hex=41
中.hex=4e2d
0x4e2d=中
\u4e2d=中
charset.txt文件二进制视图:

charset1.txt文件二进制视图:

在文本视图下可以显示出汉字:ucs-2 对应UTF-16
对比charst.txt文件,本文件只是多了一个UTF-16的BOM头。

charset.txt 输出代码改为如下,即与charset1一至了:
FileOutputStream fos = new FileOutputStream("charset.txt");
fos.write(0xfe);//加上UTF-16 BOM 头 高位在前 Big Endian
fos.write(0xff);
fos.write(zhong>>8);
fos.write(zhong);//用字节流输出"中"字的编码,文件中显示:4E 2A
fos.write(asciiA>>8);
fos.write(asciiA); //用字节流输出"A"字的编码,文件中显示:00 41
fos.close();
JVM 中文显示过程:
从任何数据源通过指定字符集读取字符,转换为了UTF-16保存在内存中,输出时再转换为指定的字符集输出。只要在jvm内字符的utf-16格式正确,则可以正确输出任何字符集形式。
输入数据源1:java类中写中文
javac 将java源文件编译为class文件,中文以utf-8存储,jvm启动读取class文件后,中文由UTF-8-->UTF-16。 再根据程序代码指定字符集输出。
字符集转换:utf-8-->utf-16
在JAVAC编译的时候,如果没有用-encoding参数指定JAVA源程序的编码格式,则javac.exe首先获得操作系统默认采用的编码格式System.getProperty("file.encoding")(wind7下默认字符集为GBK),认为是该源文件的编码格式。然后根据该字符集
对java源程序编译,源文件中的显示定义的中文,根据字符集读取再转换为UTF-8保存到class文件。
如果编译时使用的字符集与源文件不匹配,则:
1.编译不通过
2.以不匹配的字符集读取源文件的中文就乱码了,再换为UTF-8保存到class中也是乱码。
编码时指定源文件编码:javac -encoding GBK Test.java
如果类中写的中文,输出时乱码,则该java源文件编译时指定的字符集不正确。
java class 文件中字符以UTF-8方式保存。
public class TestClass {
static String x="中A";
}
编译为class后,查看十六进制:

E4 B8 AD 是“中”字的UTF-8编码
41是“A”字的UTF-8编码
输入数据源2:文件
java以字符流方式读取文件时,如果未指定字符集(如FileReader),则使用系统字符集,window下默认为GBK,linux下看系统配置。
字符集转换:默认或指定字符集-utf-16。
如果字符集与源文件不匹配,就会乱码。
java 参数:file.encoding 设置JAVA reader writer IO时默认的字符集(对应读取、写入文件、编译JAVA源文W件)。

以上为UTF-8格式文件,不指定字符集,则按默认字符集(GBK)读取,为乱码:

二种方式解决:
1.在运行时指定-Dfile.encoding=UTF-8

2.指定读取文件的字符集
BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream("c:\\charset.txt"),"UTF-8"));
输入数据源3:数据库
java 读取数据库是通过jdbc驱动, 驱动由数据库厂商实现,在厂商需要实现ResultSet接口:
ResultSet API:
Object |
getObject(int columnIndex) 以 Java 编程语言中 Object 的形式获取此 ResultSet 对象的当前行中指定列的值。 |
String |
getString(int columnIndex) 以 Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指定列的值。 |
如果通过ResultSet 获取出来的数据是乱码,则为驱动问题或驱动参数问题 。
jdbc驱动以指定字符集(或默认字符集)等方式读取出来的数据,为GBK格式或UTF-8格式,都可以正确的转换为jvm内部的utf-16。
字符集转换:默认或指定字符集-UTF-16。
输出到控制台:System.out
System.out 对象输出的数据,采用系统默认字符集输出。
字符集转换:utf-16 ->默认字符集
输出到文件
使用FileWriter :采用系统默认字符集。
或使用指定字符集的Writer对象。
字符集转换:utf-16 ->默认或指定字符集
输出到数据库:
字符集转换: utf-16 ->默认或指定字符集

- 大小: 3.1 KB

- 大小: 6.3 KB

- 大小: 7.6 KB

- 大小: 2.8 KB

- 大小: 967 Bytes

- 大小: 2.5 KB

- 大小: 3.4 KB

- 大小: 1 KB

- 大小: 1.7 KB

- 大小: 2.5 KB

- 大小: 2.8 KB

- 大小: 3.7 KB
分享到:
相关推荐
在深入探讨JAVA与字符集编码问题之前,我们首先需要理解不同字符集编码的基本概念以及它们在JAVA环境中的应用。字符集编码是计算机系统中表示文字的一种方式,它决定了如何将字符转换为二进制数据,以便于存储和传输...
在Java开发中,连接Oracle数据库是一项常见的任务,尤其是在处理特定字符集如American ASCII7时,开发者需要对字符编码有深入的理解。Oracle数据库支持多种字符集,包括ASCII,它是最基础的7位字符集,包含32个控制...
### Java支持的字符集 Java作为一种广泛使用的编程语言,在处理多语言环境下的文本时,其对字符集的支持显得尤为重要。本文将详细介绍Java所支持的基本字符集(Basic Encoding Set)和扩展字符集(Extended ...
### Java中的Unicode与字符集详解 #### 一、引言 在软件开发过程中,正确处理文本数据至关重要。尤其是在全球化日益加深的今天,软件不仅要能够处理英语等常见的西方语言,还要支持世界各地的语言,包括中文、日文...
### Java字符集编码乱码详解 #### 一、编码与乱码基础知识 在计算机科学领域,字符集(Character Set)是指一系列符号和电子通信代码的标准集合。每种字符集都有其特定的应用场景和优势。例如,ASCII(American ...
### Java字符集和编码 #### 一、引言 在探讨Java字符集和编码之前,我们先了解一下为什么在Java编程中需要关注字符集和编码。Java作为一种广泛应用的编程语言,其内部采用的是Unicode编码,这使得Java能够很好地...
Java中的字符集是一个重要的概念,尤其对于处理多语言文本或者跨平台的数据交换至关重要。Java语言内部使用Unicode编码,具体来说是UTF-16格式,这意味着每个`char`类型变量能够表示一个Unicode字符,通常占据两个...
本文将围绕“Java字符集编码简记”这一主题,深入探讨相关知识点,并结合标签“源码”和“工具”,探讨在实际开发中如何运用和处理字符编码问题。 首先,我们需要理解字符集的概念。字符集是一系列符号的集合,例如...
java字符集
### Java字符集编码问题详解 #### 一、引言 在Java编程中,字符集编码问题是一个常见且重要的议题。由于不同的系统、平台以及网络环境中可能存在多种字符编码格式,这导致了在处理文本数据时可能会遇到编码不一致...
本文将深入探讨Java中的输入输出流以及字符集的相关知识点。 一、Java IO流概述 Java的IO流模型是基于管道的概念,数据在不同设备之间流动就像水流在管道中传输一样。流可以分为四类:字节流(Byte Stream)和字符...
java 字符集编码转换,时间格式化,数字判断等,java文件
在Java编程语言中,字符集(Charset)是用于表示文本数据的一系列规则,它定义了字符与二进制数据之间的映射关系。...以上就是关于Java字符集解码方法的详细说明,希望对您理解Java字符集处理有所帮助。
在Java编程中,正确地处理文件的字符集编码至关重要,特别是在读取或写入含有非ASCII字符(如中文、日文、韩文等)的文件时。`cpdetector`是Java中一个常用的库,用于自动检测文件的字符集编码。这个库能够帮助...
Java字符集是一个涵盖编码基础知识、Java编程环境与字符编码关系以及不同编码标准如何在Java中应用的主题。在本文中,我们将深入探讨这些方面,以便更好地理解Java如何处理各种字符编码。 首先,我们要明白编码的...
然而,当Java程序与操作系统(如文件系统)交互时,就需要进行编码转换。因为文件系统可能使用不同的编码,如GBK、ISO-8859-1或UTF-8等。Java的IO系统在此起到了关键作用,它分为面向字节的流(如InputStream和...
Java的字符集
在Java编程语言中,理解和掌握字符集编码是至关重要的,特别是在处理各种文本数据时。本文主要探讨了编码字符集和字符集编码的区别,这对于软件开发人员来说是基础且必要的知识。 首先,我们要区分两个概念:编码...
通用的文件字符编码集判断需要借助第三方包cpdetector.jar 使用Cpdetector jar包检测文件编码需要依赖antlr-2.7.7.jar、chardet-1.0.jar、jargs-1.0.jar三个jar包 本下载资源一站式全包含,并附带亲测有效的片段...