文档章节

Java NIO之字符集

士别三日
 士别三日
发布于 06/24 18:43
字数 1470
阅读 17
收藏 0

1 字符集和编解码的概念

首先,解释一下什么是字符集。顾名思义,就是字符的集合。它的初衷是把现实世界的符号映射为计算机可以理解的字节。比如我创造一个字符集,叫做sex字符集,就包含两个字符{‘男’,‘女’}。然后把‘男’编码为0,‘女’编码为1。你搬把凳子坐在店门口,进来一个男的你记为0,进来一个女的你记为1。一天下来,你只要把这些0和1输入计算机,计算机就会解码出结果告诉大家今天进来多少男的,进来多少女的,顺序是怎样的……标准化的字符集也是差不多道理,不同的是字符数量比sex字符集大得多。在编解码方面,都是为了容纳必须的字符,然后尽可能地节省存储空间和提升编解码效率。在计算机的世界,一般是以字节为单位存储数据的,一个字节包含8位。所以一个字节有256种变化。

最初计算机发明于拉丁字母世界国家,用ASCII字符集既可以满足基本需求了。ASCII字符集包含256个字符,所以每个字符用一个字节表示就可以。这是最简单的编解码方式。

后来计算机扩展到了全世界,一开始每个文化区域根据自己的需要各自制定自己的字符集标准。比如中国就先后出现了GB232/GBK/GB18030/BIG5……字符集。GB232字符集包含了常用的汉字,但是有些生僻字没有包含进去,GBK收录了更多的汉字,BIG5还收录了繁体字。其他国家也会有自己的字符集。如果每个文化区域使用不同的字符集,那么地区和地区之间将没法交流。所以后来出现了国际化的字符集。

Unicode字符集是通用字符集(Universal Character Set)。它试图把世界上所有的字符都收罗进去。要知道,世界在发展,符号是映射真实世界的工具。真实世界越复杂,就需要更多的符号。所以Unicode字符集里面的字符数量一直在增加。其实,全世界只需要一个字符集,字符集的内容也应该是动态发展的,所以Unicode字符集时不时就要发一次版。

但是字符集全世界可以共用一个,也应该共用一个。但是对同一个字符集,可以有多种编解码方式,下面是对Unicode字符集的编解码方式:

  • UTF-32。每个字符都用四个字节(32位)来表达。缺点是浪费内存空间,优点是解码方便,四个四个字节进行解码就行了。
  • UTF-16。虽然世界上的字符很多,但是常用的字符不多,大部分人不会用到超过前65535个以外的字符。对于前65535个常用字符,可以用两个字节(16位)来编码,其他字符就用四个字节来编码。这样可以大大节省内存,大概节省一半。但是编码解码的效率会更低。
  • UTF-8。根据不同的范围用1~4个字节编码一个字符。兼容ASCII字符集的编解码方式。也就是说前256个字符和ASCII一致,编码解码也一样。因为这种兼容性,导致这种编码方式应用最广泛。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。

 

2 NIO中的Charset类

现在言归正传,讨论一下java.nio中的Charset类。Charset类主要功能是提供特定的编解码方式。把字符转成字节就是编码,把字节转成字符就是解码。

我们可以用代码确定JDK默认安装的所有编码模式:

SortedMap<String,Charset> charsets = Charset.availableCharsets();
for(String name:charsets.keySet()) {
	System.out.println(name);
}

Big5
Big5-HKSCS
CESU-8
EUC-JP
EUC-KR
GB18030
GB2312
GBK
IBM-Thai
IBM00858
IBM01140
IBM01141
IBM01142
IBM01143
IBM01144
IBM01145
IBM01146
IBM01147
IBM01148
IBM01149
IBM037
IBM1026
IBM1047
IBM273
IBM277
IBM278
IBM280
IBM284
IBM285
IBM290
IBM297
IBM420
IBM424
IBM437
IBM500
IBM775
IBM850
IBM852
IBM855
IBM857
IBM860
IBM861
IBM862
IBM863
IBM864
IBM865
IBM866
IBM868
IBM869
IBM870
IBM871
IBM918
ISO-2022-CN
ISO-2022-JP
ISO-2022-JP-2
ISO-2022-KR
ISO-8859-1
ISO-8859-13
ISO-8859-15
ISO-8859-2
ISO-8859-3
ISO-8859-4
ISO-8859-5
ISO-8859-6
ISO-8859-7
ISO-8859-8
ISO-8859-9
JIS_X0201
JIS_X0212-1990
KOI8-R
KOI8-U
Shift_JIS
TIS-620
US-ASCII
UTF-16
UTF-16BE
UTF-16LE
UTF-32
UTF-32BE
UTF-32LE
UTF-8

...

字符集的名字大小写是不敏感的,而且每一种字符集编码名称都可能有多个别名:

Charset charset = Charset.forName("ISO-8859-15");
Set<String> aliases = charset.aliases();
for(String aliase:aliases) {
	System.out.println(aliase);
}

 ISO8859-15
LATIN0
ISO8859_15_FDIS
ISO8859_15
cp923
8859_15
L9
ISO-8859-15
IBM923
csISOlatin9
ISO_8859-15
IBM-923
csISOlatin0
923
LATIN9

再来看一下编码和解码的代码:

//用UTF-16编码
Charset charset = Charset.forName("UTF-16");
ByteBuffer buffer = charset.encode("大家好");
//用UTF-16解码
CharBuffer cbuf = charset.decode(buffer);
System.out.println(cbuf.toString());
//用UTF-8解码,出现乱码		
Charset charset1 = Charset.forName("UTF-8");
buffer.rewind();
CharBuffer cbuf1 = charset1.decode(buffer);
System.out.println(cbuf1.toString());

 大家好
��Y'[�Y}

 3 总结

一般互联网协议和Java代码使用的都是UTF-8。所以一般情况下不需要指明用哪种Charset。但是如果在特殊情况下,比如合作方已经用了某种字符集编解码模式,就可以运用本文的知识进行对接。

© 著作权归作者所有

共有 人打赏支持
士别三日

士别三日

粉丝 38
博文 30
码字总数 43081
作品 0
深圳
程序员
分别使用Java IO、NIO、Netty实现的一个Echo Server示例

分别使用Java IO、Java NIO、Netty来实现一个简单的EchoServer(即原样返回客户端的输入信息)。 Java IO int port = 9000;ServerSocket ss = new ServerSocket(port);while (true) {final S...

zgw06629
2015/05/24
0
0
Java NIO AsynchronousFileChannel

原文链接 , 原文作者:Jakob Jenkov, 翻译:Neil Hao 在Java 7,AsynchronousFileChannel 被添加到了Java NIO中。使用AsynchronousFileChannel可以实现异步地读取和写入文件数据。 创建一个A...

Neil_Hao
01/20
0
0
Java NIO原理 图文分析及代码实现

Java NIO原理图文分析及代码实现 前言: 最近在分析hadoop的RPC(Remote Procedure Call Protocol ,远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术...

囚兔
2015/04/29
0
0
Java NIO原理图文分析及代码实现

前言: 最近在分析hadoop的RPC(Remote Procedure Call Protocol ,远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。可以参考:http://baik...

SunnyWu
2014/11/05
0
1
java NIO:IO与NIO的区别

一、概念 NIO即New IO,这个库是在JDK1.4中才引入的。NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多。在Java API中提供了两套NIO,一套是针对标...

盼望明天
09/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

正弦 余弦 角度 用于画时钟

<html> <head> <title>时钟</title> </head> <style> #canvas{ background: #1977ca } </style>......

一箭落旄头
24分钟前
1
0
drupal7自定义模块之表单(新手向)

前段时间要给网站做个高级搜索的功能,但drupal7自带的搜索远远无法满足需求,便有了自己开发的需求 我以前没有接触过drupal,做这个功能也是困难重重,几乎是从零开始,我将目光放到了自定义模块...

gcudwork
29分钟前
0
0
驰狼课堂

http://www.chilangedu.com/

求是科技
47分钟前
0
0
jumpserver 报错"Incorrect string value

申明 本文所有内容参考自jumpserver记录命令无法入库问题 #1773 简介 jumpserver 1.4.0在jumpserver.log中大量报错,错误日志 File "/opt/jumpserver/apps/terminal/api.py", line 246, i...

zhnxin
53分钟前
2
0
用户管理相关配置文件及命令

9月19日任务 2.27linux和windows互传文件 3.1 用户配置文件和密码配置文件 3.2 用户组管理 3.3 用户管理 扩展知识 实用小工具 简单命令行下实现Linux/Windows文件互传 前提:使用远程工具Xsh...

robertt15
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部