nio系列(一)---nio重要组成
nio重要组成部分
前言:通过本文可以了解nio的重要组成部分,了解完基础的内容后后面理解才会简单一点。下一篇会讲讲nio的应用和io的对比。如果有不正确的地方还望指正。
channel
chanel接口的实现类
- FileChannel 从文件中读取数据
- DatagramChannel 通过udp读取网络中数据
- SocketChannel 通过tcp读取网络中的数据
- SeverSocketChannel 可以监听新进来的TCP连接,每一个新进来的连接都会创建一个SocketChanel
通道的注意点
- 通道可以是单向也可是双向的,同时实现ReadableByteChannel和WritableByteChannel接口可以实现双向运输
RandomAccessFile aFile = new RandomAccessFile("C:\\Users\\jiajun\\Desktop\\Test.txt", "rw");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf=ByteBuffer.allocate(20);
inChannel.read(buf);
buf.flip();
inChannel.write(buf);
inChannel.close();
//文件中本来有3个6,执行操作后有6个6
- 通道可以阻塞也可以非阻塞,configureBlocking(boolean block)设置是否阻塞
- 通道必须在缓冲区上操作,从缓冲区写入到通道或者通道写入到缓冲区
Socket通道类
- SocketChannel和ServerSocketChannel对应java.net包中的Socket和ServerSocket
- 通道类的socket方法可以获取Socket对象
打开socketChannel和ServerSocketChannel
socketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress(ip, 80));
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
非阻塞和阻塞
- 在阻塞的情况下,accept方法会一直阻塞到有新连接到达
SocketChannel socketChannel = serverSocketChannel.accept();
//do something with socketChannel...
- 在非阻塞情况下,accept方法会立即返回,如果还没有新的连接到达,返回null
SocketChannel socketChannel =serverSocketChannel.accept();
//do something with socketChannel...
Buffer
Buffer类的子类
- ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer
Buffer属性
- 容量(capacity):所包含元素的数量,也就allocate分配的大小
- 限制(limit):第一个不应该读取或写入的元素的索引,查看缓冲区中是否还有数据的时候会用到
- 位置(position):下一个要读取或写入的元素的索引
- 标志(mark):调用mark()来设置mark=position,再调用reset()可以让position恢复到标记的位置即position=mark
重要方法
- hasRemaining(),在缓冲区读取数据的时候用到,判断缓冲区是否还有数据
public final boolean hasRemaining() {
return position < limit;
}
- clear() 使缓冲区为一系列新的通道读取或相对放置 操作做好准备。它将限制设置为容量大小,将位置设置为 0。
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
- flip() 使缓冲区为一系列新的通道写入或相对获取 操作做好准备:它将限制设置为当前位置,然后将位置设置为 0。
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
- rewind():将position设回0,可以重读Buffer中的所有数据
public final Buffer rewind() {
position = 0;
mark = -1;
return this;
}
例子
- 创建一个字符串数组,读写完一个字符串到缓冲区,就从缓冲区读取字符串
public class TestMain
{
private static String[] strs =
{
"jiajun",
"jiajun6",
"jiajun66",
"jiajun666",
};
/**
* 标识strs的下标索引
*/
private static int index = 0;
/**
* 向Buffer内放置数据
*/
private static boolean fillBuffer(CharBuffer buffer)
{
if (index >= strs.length)
return false;
String str = strs[index++];
for (int i = 0; i < str.length(); i++)
{
buffer.put(str.charAt(i));
}
return true;
}
/**
* 从Buffer内把数据拿出来
*/
private static void drainBuffer(CharBuffer buffer)
{
while (buffer.hasRemaining())
{
System.out.print(buffer.get());
}
System.out.println("");
}
public static void main(String[] args)
{
CharBuffer cb = CharBuffer.allocate(100);
while (fillBuffer(cb))
{
System.out.println("缓冲区的position:"+cb.position()+",缓冲区的limit:"+cb.limit()+",缓冲区的capacity:"+cb.capacity());
cb.flip();
System.out.println("执行filp方法后缓冲区的position:"+cb.position()+",缓冲区的limit:"+cb.limit()+",缓冲区的capacity:"+cb.capacity());
drainBuffer(cb);
cb.clear();
System.out.println("-----------------");
}
}
}
- 输出结果
缓冲区的position:6,缓冲区的limit:100,缓冲区的capacity:100
执行filp方法后缓冲区的position:0,缓冲区的limit:6,缓冲区的capacity:100
jiajun
-----------------
缓冲区的position:7,缓冲区的limit:100,缓冲区的capacity:100
执行filp方法后缓冲区的position:0,缓冲区的limit:7,缓冲区的capacity:100
jiajun6
-----------------
缓冲区的position:8,缓冲区的limit:100,缓冲区的capacity:100
执行filp方法后缓冲区的position:0,缓冲区的limit:8,缓冲区的capacity:100
jiajun66
-----------------
缓冲区的position:9,缓冲区的limit:100,缓冲区的capacity:100
执行filp方法后缓冲区的position:0,缓冲区的limit:9,缓冲区的capacity:100
jiajun666
-----------------
Selector
监听事件
- Selector对监听的channel的什么事件感兴趣
- SelectionKey.OP_CONNECT,channel成功连接到另一个服务器为连接就绪
- SelectionKey.OP_ACCEPT,ServerSocketChannel准备好接受新进入的链接为接受就绪
- SelectionKey.OP_READ,一个有数据可读的通道为读就绪
- SelectionKey.OP_WRITE,等待写数据的通道为写就绪
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.register(selector, SelectionKey.OP_ACCEPT);
//比如这里Selector对SeverSocketChannel的连接就绪感事件兴趣
SelectionKey
- 向Selector注册Channel时,regist方法会返回一个SelectionKey对象,代表了注册到Selector的通道
public final SelectionKey register(Selector sel,int ops)throws ClosedChannelException
interest集合,所选择的感兴趣的事件集合,通过SelectionKey的interestOps()方法获取感兴趣事件结合,如果设置的为SelectionKey.OP_CONNECT,那么该方法返回SelectionKey.OP_CONNECT的值
selectionKey.isAcceptable() 检查channel是否接受就绪
selectionKey.isConnectable(),检查channel是否连接就绪
selectionKey.isReadable(),检查channel是否读就绪
selectionKey.isWritable(),检查channel是否写就绪
select方法
- 如果Selector注册的channel的感兴趣的事件还没有就绪,那么会阻塞
- 当至少有一个channel的注册时间就绪的时候返回,返回的是自上次调用select()方法后有多少通道变成就绪状态
- select(long timeout):执行选择,超过指定毫秒数则返回
- selectNow():立刻执行选择,非阻塞,若没有已准备好的通道则立即返回0
public abstract int select()throws IOException
wakeUp方法
- 当执行select方法后阻塞了,可以使用wakeup方法使阻塞在select方法的线程返回
selectKeys方法
- 返回此选择器已选择键集,通过该方法返回的集合来访问就绪的的通道
- 注意每次迭代末尾的keyIterator.remove()调用。Selector不会自己从已选择键集中移除SelectionKey实例。必须在处理完通道时自己移除。下次该通道变成就绪时,Selector会再次将其放入已选择键集中。
public abstract Set<SelectionKey> selectedKeys()
我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)
作者:jiajun 出处: http://www.cnblogs.com/-new/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。
nio系列(一)---nio重要组成的更多相关文章
- java nio系列文章
java nio系列教程 基于NIO的Client/Server程序实践 (推荐) java nio与并发编程相关电子书籍 (访问密码 48dd) 理解NIO nio学习记录 图解ByteBuff ...
- Java NIO 系列教程(转)
原文中说了最重要的3个概念,Channel 通道Buffer 缓冲区Selector 选择器其中Channel对应以前的流,Buffer不是什么新东西,Selector是因为nio可以使用异步的非堵塞 ...
- Java NIO系列1-概观
Java NIO系列1-概观 Java NIO.中间的N你既可以理解为(new),也就是新的IO,相对于java1.5之前的IO它确实是新的;也可以理解为(no-blocking),也就是非阻塞的IO ...
- Java NIO系列教程(八)JDK AIO编程
目录: Reactor(反应堆)和Proactor(前摄器) <I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor> <[转]第8章 前摄器(Proa ...
- Java NIO系列教程(七) selector原理 Epoll版的Selector
目录: Reactor(反应堆)和Proactor(前摄器) <I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor> <[转]第8章 前摄器(Proa ...
- Java NIO系列教程(一)java NIO简介
这个系列的文章,我们开始玩一玩IO方面的知识,对于IO和NIO,我们经常会接触到,了解他们的基本内容,对于我们的工作会有特别大的帮助.这篇博文我们仅仅是介绍IO和NIO的基本概念,以及一些关键词. 基 ...
- Java NIO系列教程(三) Channel之Socket通道
目录: <Java NIO系列教程(二) Channel> <Java NIO系列教程(三) Channel之Socket通道> 在<Java NIO系列教程(二) Ch ...
- Java NIO系列教程(二) Channel通道介绍及FileChannel详解
目录: <Java NIO系列教程(二) Channel> <Java NIO系列教程(三) Channel之Socket通道> Channel是一个通道,可以通过它读取和写入 ...
- Java NIO系列教程(十一) Java NIO 与 IO
Java NIO系列教程(十一) Java NIO与IO 当学习了 Java NIO 和 IO 的 API 后,一个问题马上涌入脑海: 我应该何时使用 IO,何时使用 NIO 呢?在本文中,我会尽量清 ...
- Java NIO系列教程(十)DatagramChannel
Java NIO系列教程(十)DatagramChannel 转载自并发编程网 – ifeve.com,本文链接地址: Java NIO系列教程(十) Java NIO DatagramChannel
随机推荐
- Object-C知识点 (三) 单例 蒙版 刷新 KVO底层
#pragma mark - 单例方法(完整的方法) 系统的单例方法名称 sharedApplication defaultManager standardUserDefaults currentDe ...
- JavaScript学习笔记(一)——初识js
这个周,开始了JavaScript的学习路程.虽然从高中开始就接触了网页设计的知识,大学里的学习也算回顾了Html和Css的知识,实习期间在牛盾科技也是做的网站建设,不过通过前段时间找工作才发现自己了 ...
- js实现类似iphone的秒表-添加平均数功能
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- Django开发的基于markdown的博客开源
PiperMarkdown Blog for Django1.11,Python 3.6,based on Markdown,网址,希望大家能给个star,谢谢! 什么是PiperMarkdown 这 ...
- unslider插件的使用
深入理解unslider.js源码 最近用到了一个挺好用的幻灯片插件,叫做unslider.js,就想看看怎么实现幻灯片功能,就看看源码,顺便自己也学习学习.看完之后收获很多,这里和大家分享一下. u ...
- POJ 3041 Asteroids / UESTC 253 Asteroids(二分图最大匹配,最小点匹配)
POJ 3041 Asteroids / UESTC 253 Asteroids(二分图最大匹配,最小点匹配) Description Bessie wants to navigate her spa ...
- CJOJ 1071 【Uva】硬币问题(动态规划)
CJOJ 1071 [Uva]硬币问题(动态规划) Description 有n种硬币,面值分别为v1, v2, ..., vn,每种都有无限多.给定非负整数S,可以选用多少个硬币,使得面值之和恰好为 ...
- JS - 讨论 - 编码习惯 - JavaScript代码到底要不要写分号?
如题:烦请大家在评论区给出原创意见!多谢!
- 还在为画“类Word文档报表”而发愁吗?
欢迎大家持续关注葡萄城控件技术团队博客,更多更好的原创文章尽在这里~~ Word 是非常强大的文档编辑工具,一些行业制式文档都是使用Word来创建的,像教育行业的申请表,履历表,审批表等,像石油业的 ...
- TCP简单通讯
客户端代码: package com.kaige123.net01; import java.io.IOException; import java.io.InputStream; import ja ...