Java nio 学习笔记(二) Charset(字符集)与Selector(异步IO)的知识
2012-03-16 15:47
441 查看
三.Charset(字符集)
在java.nio.charset包中共提供了Charset、CharsetDecoder、CharsetEncoder、CodeResult、CodingErrorAction五个类,均继承自Object类,其中Charset实现了Comparable接口,其它类均为自身实现。
Java中的字符使用unicode编码,每个字符占用两个字节。字节码本身只是一些数字,放在正确的上下文中可以被正确的解析。向ByteBuffer中存放数据时需要考虑字符集的编码方式,从中读取时需要考虑字符集的解码。
要读和写文本需要分别使用CharsetDecoder(解码器)和CharsetEncoder(编码器)。
编码:百科中这样定义,编码(coding)是在一个主题或单元上为数据存储,管理和分析的目的而转换信息为编码值(典型地如数字)的过程。在密码学中,编码是指在编码或密码中写的行为。n位二进制数可以组合成2的n次方个不同的信息,给每个信息规定一个具体码组,这种过程也叫编码。数字系统中常用的编码有两类,一类是二进制编码,另一类是二—十进制编码。
(1)如何得到一个CharSet?
在JDK源码中提供两种方式得到一个CharSet实例:
第一种方法返回一个指定字符格式的CharSet,第二种方法返回当前虚拟机默认的字符编码格式的CharSet。
(2)如何使用CharSet?
得到一个CharSet实例后,我们需要创建一个编码器和一个解码器,使用下面方法进行创建:
接着我们把ByteBuffer传递给decoder进行编码,返回一个CharBuffer:
然后我们可以使用encoder进行解码返回一个ByteBuffer:
接下来可以进行写等其它操作。
四.Selector(异步IO)
异步IO是一种没有阻塞的读写数据的方法,通常,在代码进行 read() 调用时,代码会阻塞直至有可供读取的数据。同样,write() 调用将会阻塞直至数据能够写入。
异步 I/O 的一个优势在于,它允许您同时根据大量的输入和输出执行 I/O。同步程序常常要求助于轮询,或者创建许许多多的线程以处理大量的连接。使用异步 I/O,您可以监听任何数量的通道上的事件,不用轮询,也不用额外的线程。
异步 I/O 中的核心对象名为 Selector。Selector 就是您注册对各种 I/O 事件的地方,而且当那些事件发生时,就是这个对象告诉您所发生的事件。
第一步:创建一个Selector
第二步:打开一个远程连接
注册读事件:
首先,我们调用 Selector 的 select() 方法。这个方法会阻塞,直到至少有一个已注册的事件发生。当一个或者更多的事件发生时, select() 方法将返回所发生的事件的数量。该方法必须首先执行。
接下来,我们调用 Selector 的 selectedKeys() 方法,它返回发生了事件的 SelectionKey 对象的一个 集合 。
我们通过迭代 SelectionKeys 并依次处理每个 SelectionKey 来处理事件。对于每一个 SelectionKey,您必须确定发生的是什么 I/O 事件,以及这个事件影响哪些 I/O 对象。
第五步:监听事件并做出处理
SelectionKey中共定义了四种事件,OP_ACCEPT(socket accept)、OP_CONNECT(socket connect)、OP_READ(read)、OP_WRITE(write)。
第六步:删除处理过的SelectionKey
在处理 SelectionKey 之后,我们几乎可以返回主循环了。但是我们必须首先将处理过的 SelectionKey 从选定的键集合中删除。
如果我们没有删除处理过的键,那么它仍然会在主集合中以一个激活的键出现,这会导致我们尝试再次处理它。
我们调用迭代器的 remove() 方法来删除处理过的 SelectionKey:it.remove();
在java.nio.charset包中共提供了Charset、CharsetDecoder、CharsetEncoder、CodeResult、CodingErrorAction五个类,均继承自Object类,其中Charset实现了Comparable接口,其它类均为自身实现。
Java中的字符使用unicode编码,每个字符占用两个字节。字节码本身只是一些数字,放在正确的上下文中可以被正确的解析。向ByteBuffer中存放数据时需要考虑字符集的编码方式,从中读取时需要考虑字符集的解码。
要读和写文本需要分别使用CharsetDecoder(解码器)和CharsetEncoder(编码器)。
编码:百科中这样定义,编码(coding)是在一个主题或单元上为数据存储,管理和分析的目的而转换信息为编码值(典型地如数字)的过程。在密码学中,编码是指在编码或密码中写的行为。n位二进制数可以组合成2的n次方个不同的信息,给每个信息规定一个具体码组,这种过程也叫编码。数字系统中常用的编码有两类,一类是二进制编码,另一类是二—十进制编码。
(1)如何得到一个CharSet?
在JDK源码中提供两种方式得到一个CharSet实例:
CharSet cs = CharSet.forName(“编码方式”); CharSet cs = CharSet.defaultCharSet();
第一种方法返回一个指定字符格式的CharSet,第二种方法返回当前虚拟机默认的字符编码格式的CharSet。
(2)如何使用CharSet?
得到一个CharSet实例后,我们需要创建一个编码器和一个解码器,使用下面方法进行创建:
CharSetDecoder decoder = cs.newDecoder(); CharSetEncoder encoder = cs.newEncoder();
接着我们把ByteBuffer传递给decoder进行编码,返回一个CharBuffer:
CharBuffer cb = decoder.decode(inputData);
然后我们可以使用encoder进行解码返回一个ByteBuffer:
ByteBuffer outputData = encoder.encode(cb);
接下来可以进行写等其它操作。
四.Selector(异步IO)
异步IO是一种没有阻塞的读写数据的方法,通常,在代码进行 read() 调用时,代码会阻塞直至有可供读取的数据。同样,write() 调用将会阻塞直至数据能够写入。
异步 I/O 的一个优势在于,它允许您同时根据大量的输入和输出执行 I/O。同步程序常常要求助于轮询,或者创建许许多多的线程以处理大量的连接。使用异步 I/O,您可以监听任何数量的通道上的事件,不用轮询,也不用额外的线程。
异步 I/O 中的核心对象名为 Selector。Selector 就是您注册对各种 I/O 事件的地方,而且当那些事件发生时,就是这个对象告诉您所发生的事件。
第一步:创建一个Selector
Selector selector = Selector.open();
第二步:打开一个远程连接
InetSocketAddress socketAddress = new InetSocketAddress("www.baidu.com", 80); SocketChannel sc = SocketChannel.open(socketAddress); sc.configureBlocking(false);第三步:选择键,注册
SelectionKey key = sc.register(selector, SelectionKey.OP_CONNECT);注册时第一个参数总是当前的这个selector。
注册读事件:
SelectionKey key = sc.register(selector, SelectionKey.OP_READ);注册写事件
SelectionKey key = sc.register(selector, SelectionKey.OP_WRITE);第四步:内部循环处理
int num = selector.select(); Set selectedKeys = selector.selectedKeys(); Iterator it = selectedKeys.iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey)it.next(); // ... deal with I/O event ... }
首先,我们调用 Selector 的 select() 方法。这个方法会阻塞,直到至少有一个已注册的事件发生。当一个或者更多的事件发生时, select() 方法将返回所发生的事件的数量。该方法必须首先执行。
接下来,我们调用 Selector 的 selectedKeys() 方法,它返回发生了事件的 SelectionKey 对象的一个 集合 。
我们通过迭代 SelectionKeys 并依次处理每个 SelectionKey 来处理事件。对于每一个 SelectionKey,您必须确定发生的是什么 I/O 事件,以及这个事件影响哪些 I/O 对象。
第五步:监听事件并做出处理
SelectionKey中共定义了四种事件,OP_ACCEPT(socket accept)、OP_CONNECT(socket connect)、OP_READ(read)、OP_WRITE(write)。
第六步:删除处理过的SelectionKey
在处理 SelectionKey 之后,我们几乎可以返回主循环了。但是我们必须首先将处理过的 SelectionKey 从选定的键集合中删除。
如果我们没有删除处理过的键,那么它仍然会在主集合中以一个激活的键出现,这会导致我们尝试再次处理它。
我们调用迭代器的 remove() 方法来删除处理过的 SelectionKey:it.remove();
相关文章推荐
- Java nio 学习笔记(二) Charset(字符集)与Selector(异步IO)的知识
- Java nio 学习笔记(二) Charset(字符集)与Selector(异步IO)的知识
- Java nio 学习笔记(二) Charset(字符集)与Selector(异步IO)的知识
- Mysql DBA 高级运维学习笔记-Mysql数据库字符集知识
- java NIO入门简介 Charset(字符集)与Selector(异步IO)的知识
- Java nio 学习笔记(一) Buffer(缓冲区)与Channel(通道)的相关知识
- Java NIO学习笔记-Selector
- Linux运维学习笔记-角色知识总结
- 学习笔记之微服务构建Spring Boot基础知识
- Object-C学习笔记二-----面向对象编程基础知识
- Flume NG 学习笔记(六)Selector(复用与复制)测试
- [学习笔记]关于数据库连接池技术的理论知识(学习其他人的文章)
- 【2018.03.29学习笔记】【linux基础知识2.18-2.22】
- 【知了堂学习笔记】_Jquery基础知识之DOM操作(二)
- unittest -官网文档学习笔记-基本知识
- C++ Primer 学习笔记-基础知识(二)
- Unity3D笔记(一)基础知识学习笔记
- 受限玻尔兹曼机(RBM)学习笔记(一)预备知识
- 字符集和字符编码学习笔记
- C++基础学习笔记----第二课(引用的基础知识)