`

JAVA 与字符集

 
阅读更多

字符集:

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-8UTF-16UTF-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环境中的应用。字符集编码是计算机系统中表示文字的一种方式,它决定了如何将字符转换为二进制数据,以便于存储和传输...

    java连接AmericanascII7字符集oracle例子

    在Java开发中,连接Oracle数据库是一项常见的任务,尤其是在处理特定字符集如American ASCII7时,开发者需要对字符编码有深入的理解。Oracle数据库支持多种字符集,包括ASCII,它是最基础的7位字符集,包含32个控制...

    java支持的字符集

    ### Java支持的字符集 Java作为一种广泛使用的编程语言,在处理多语言环境下的文本时,其对字符集的支持显得尤为重要。本文将详细介绍Java所支持的基本字符集(Basic Encoding Set)和扩展字符集(Extended ...

    Java Unicode 和字符集

    ### Java中的Unicode与字符集详解 #### 一、引言 在软件开发过程中,正确处理文本数据至关重要。尤其是在全球化日益加深的今天,软件不仅要能够处理英语等常见的西方语言,还要支持世界各地的语言,包括中文、日文...

    java字符集编码乱码详解

    ### Java字符集编码乱码详解 #### 一、编码与乱码基础知识 在计算机科学领域,字符集(Character Set)是指一系列符号和电子通信代码的标准集合。每种字符集都有其特定的应用场景和优势。例如,ASCII(American ...

    Java字符集和编码

    ### Java字符集和编码 #### 一、引言 在探讨Java字符集和编码之前,我们先了解一下为什么在Java编程中需要关注字符集和编码。Java作为一种广泛应用的编程语言,其内部采用的是Unicode编码,这使得Java能够很好地...

    Java中字符集的详细介绍

    Java中的字符集是一个重要的概念,尤其对于处理多语言文本或者跨平台的数据交换至关重要。Java语言内部使用Unicode编码,具体来说是UTF-16格式,这意味着每个`char`类型变量能够表示一个Unicode字符,通常占据两个...

    Java字符集编码简记

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

    java字符集

    java字符集

    java字符集编码问题

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

    Java io输入输出流及字符集

    本文将深入探讨Java中的输入输出流以及字符集的相关知识点。 一、Java IO流概述 Java的IO流模型是基于管道的概念,数据在不同设备之间流动就像水流在管道中传输一样。流可以分为四类:字节流(Byte Stream)和字符...

    java 字符集编码转换,时间格式化,数字判断等,java文件

    java 字符集编码转换,时间格式化,数字判断等,java文件

    java 字符集的解码方法

    在Java编程语言中,字符集(Charset)是用于表示文本数据的一系列规则,它定义了字符与二进制数据之间的映射关系。...以上就是关于Java字符集解码方法的详细说明,希望对您理解Java字符集处理有所帮助。

    java 获取文件字符集编码依赖包

    在Java编程中,正确地处理文件的字符集编码至关重要,特别是在读取或写入含有非ASCII字符(如中文、日文、韩文等)的文件时。`cpdetector`是Java中一个常用的库,用于自动检测文件的字符集编码。这个库能够帮助...

    JAVA字符集

    Java字符集是一个涵盖编码基础知识、Java编程环境与字符编码关系以及不同编码标准如何在Java中应用的主题。在本文中,我们将深入探讨这些方面,以便更好地理解Java如何处理各种字符编码。 首先,我们要明白编码的...

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

    然而,当Java程序与操作系统(如文件系统)交互时,就需要进行编码转换。因为文件系统可能使用不同的编码,如GBK、ISO-8859-1或UTF-8等。Java的IO系统在此起到了关键作用,它分为面向字节的流(如InputStream和...

    Java的字符集包括UTF-8

    Java的字符集

    Java中的字符集编码入门(二)编码字符集与字符集编码的区别[参考].pdf

    在Java编程语言中,理解和掌握字符集编码是至关重要的,特别是在处理各种文本数据时。本文主要探讨了编码字符集和字符集编码的区别,这对于软件开发人员来说是基础且必要的知识。 首先,我们要区分两个概念:编码...

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

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

Global site tag (gtag.js) - Google Analytics