文档章节

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。但是如果在特殊情况下,比如合作方已经用了某种字符集编解码模式,就可以运用本文的知识进行对接。

© 著作权归作者所有

共有 人打赏支持
上一篇: Java NIO
士别三日

士别三日

粉丝 38
博文 30
码字总数 43081
作品 0
深圳
程序员
私信 提问
Java NIO AsynchronousFileChannel

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

Neil_Hao
01/20
0
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原理 图文分析及代码实现

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编程入门(一)

JAVA NIO编程入门(一) 一、前言 笔者之前接触的NIO编程比较少,所以对这一块的基础也比较弱,NIO作为java编程中一个重要的模块,不能很好的掌握它,感觉自己在java方面就掌握的不够,所以,...

木木匠
09/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7.4 搭建 ss

一键安装 shadowsocks-go 版 wget –no-check-certificate https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-go.sh chmod +x shadowsocks-go.sh ./s......

YunOu
15分钟前
2
0
Spark Streaming整合kafka实战

kafka作为一个实时的分布式消息队列,实时的生产和消费消息,这里我们可以利用SparkStreaming实时计算框架实时地读取kafka中的数据然后进行计算。在spark1.3版本后,kafkaUtils里面提供了两个...

hblt-j
16分钟前
1
0
vue组件中的样式属性scoped实例

vue组件中的style标签标有scoped属性时表明style里的css样式只适用于当前组件元素 。接下来通过本文给大家分享vue组件中的样式属性scoped实例详解 **Scoped CSS** Scoped CSS规范是Web组件产...

前端攻城老湿
31分钟前
2
0
ios 面试部分整理

assign weak区别 assign不是有崩溃的风险么 strong和copy 对非容器类可变类型 非容器类不可变 容器类可变容器类不可变 进行深拷贝浅拷贝有什么区别 什么样的对象可以进行拷贝 就是这个NScod...

大魔王周晓辉
32分钟前
2
0
浅谈教你如何掌握Linux系统

linux能做什么?相信绝大数人都有这样的疑问。可以玩吃鸡吗?可以玩lol吗? 如果你是以娱乐的名义来评价linux的可用性,对不起,linux可能不适合你,因为linux是一个工具,他是教你聪明的,不...

Linux就该这么学
32分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部