1.1. Java NIO Channel的特点

和老的OIO相比,通道和NIO流(非阻塞IO)主要有以下几点区别:

(1)OIO流一般来说是单向的(只能读或者写),通道可以读也可以写。

(2)OIO流值读写阻塞的,而通道可以异步读写。

(3)通道总是基于缓冲区Buffer来读写。

1.2. Channel类型

下面列出Java NIO中最重要的集中Channel的实现:

(1)FileChannel

(2)DatagramChannel

(3)SocketChannel

(4)ServerSocketChannel

四种通道的说明如下:

FileChannel 用于文件的数据读写。

DatagramChannel 用于UDP的数据读写。

SocketChannel 用于TCP的数据读写。

ServerSocketChannel 允许我们监听TCP链接请求,每个请求会创建会一个SocketChannel。

这个四种通道,涵盖了 UDP 和 TCP网络 IO以及文件 IO的操作。下面从通道的新建、读取、写入、关闭等四个操作,四种通道进行简单的介绍。

1.3. FileChannel

FileChannel 是操作文件的Channel,我们可以通过 FileChannel 从一个文件中读取数据,也可以将数据写入到文件中。

注意,FileChannel 不能设置为非阻塞模式。

操作一:打开 FileChannel通道

RandomAccessFile aFile = new RandomAccessFile("test.txt","rw");

FileChannel inChannel= aFile.getChannel();

操作二:读取数据

ByteBuffer buf = ByteBuffer.allocate(48);int bytesRead = inChannel.read(buf);

操作三:写入数据

String newData = "New String to write to file..." +System.currentTimeMillis();

ByteBuffer buf= ByteBuffer.allocate(48);

buf.clear();

buf.put(newData.getBytes());

buf.flip();while(buf.hasRemaining())

{

channel.write(buf);

}

操作四:关闭

channel.close();

当我们对 FileChannel 的操作完成后,必须将其关闭。

操作五:强制刷新磁盘

channel.force(true);

FileChannel的force()方法将所有未写入的数据从通道刷新到磁盘中。在你调用该force()方法之前,出于性能原因,操作系统可能会将数据缓存在内存中,因此您不能保证写入通道的数据实际上写入磁盘。

1.4. SocketChannel

有两种Socket通道,一个是客户端的SocketChannel,一个是负责服务器端的Socket通道ServerSocketChannel。SocketChannel与OIO中的Socket类对应,ServerSocketChannel对应于OIO中的ServerSocket类相NIO。

两种Socket通道新增的通道都支持阻塞和非阻塞两种模式。在阻塞模式下的通道的创建、关闭、读写操作如下:

操作一:创建

SocketChannel socketChannel = SocketChannel.open();

socketChannel.connect(new InetSocketAddress("127.0.0.1",80));

这个是客户端的创建。当一个服务器端的ServerSocketChannel 接受到连接请求时,也会返回一个 SocketChannel 对象。

操作二:读取

ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = socketChannel.read(buf);

如果 read()返回 -1,那么表示连接中断了.

操作三:写入数据

String newData = "New String to write to file..." +System.currentTimeMillis();

ByteBuffer buf= ByteBuffer.allocate(48);

buf.clear();

buf.put(newData.getBytes());

buf.flip();while(buf.hasRemaining()) {

channel.write(buf);

}

操作四:关闭

socketChannel.close();

在非阻塞模式,我们可以设置 SocketChannel 为异步模式,这样我们的 connect,read,write 都是异步的了.

操作一:连接

socketChannel.configureBlocking(false);

socketChannel.connect(new InetSocketAddress("127.0.0.1",80));while(!socketChannel.finishConnect() ){//wait,or do something else...

}

在异步模式中,或许连接还没有建立,socketChannel.connect 方法就返回了,因此我们不断的自旋,检查当前是否是连接到了主机。

操作二:非阻塞读写

在异步模式下,读写的方式是一样的.

在读取时,因为是异步的,因此我们必须检查 read 的返回值,来判断当前是否读取到了数据.

ServerSocketChannel

ServerSocketChannel 顾名思义,是用在服务器为端的,可以监听客户端的 TCP 连接,例如:

ServerSocketChannel serverSocketChannel =ServerSocketChannel.open();

serverSocketChannel.socket().bind(new InetSocketAddress(9999));while(true){

SocketChannel socketChannel=serverSocketChannel.accept();//do something with socketChannel...

}

操作四:关闭

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.close();

1.4.1. 监听连接

我们可以使用ServerSocketChannel.accept()方法来监听客户端的 TCP 连接请求,accept()方法会阻塞,直到有连接到来,当有连接时,这个方法会返回一个 SocketChannel 对象:

while(true){

SocketChannel socketChannel=serverSocketChannel.accept();//do something with socketChannel...

}

1.4.2. 非阻塞模式

在非阻塞模式下,accept()是非阻塞的,因此如果此时没有连接到来,那么 accept()方法会返回null:

ServerSocketChannel serverSocketChannel =ServerSocketChannel.open();

serverSocketChannel.socket().bind(new InetSocketAddress(9999));

serverSocketChannel.configureBlocking(false);while(true){

SocketChannel socketChannel=serverSocketChannel.accept();if(socketChannel != null){//do something with socketChannel...

}

}

1.5. DatagramChannel

DatagramChannel 是用来处理 UDP 连接的.

操作一:打开

DatagramChannel channel = DatagramChannel.open();

channel.socket().bind(new InetSocketAddress(9999));

操作二:读取数据

ByteBuffer buf = ByteBuffer.allocate(48);

buf.clear();

channel.receive(buf);

操作三:发送数据

String newData = "New String to write to file..." +System.currentTimeMillis();

ByteBuffer buf= ByteBuffer.allocate(48);

buf.clear();

buf.put(newData.getBytes());

buf.flip();int bytesSent = channel.send(buf,new InetSocketAddress("example.com",80));

连接到指定地址

因为 UDP 是非连接的,因此这个的 connect 并不是向 TCP 一样真正意义上的连接,因此我们仅仅可以从指定的地址中读取或写入数据.

channel.connect(new InetSocketAddress("example.com",80));

java nio oio_(三:NIO系列) Java NIO Channel相关推荐

  1. Java私塾跟我学系列——JAVA篇 第四章Java类和对象

    教学目标: i面向对象基础 i掌握对象的三大特性 i掌握Java类的构建 i掌握如何使用Java类 i理解引用类型 i理解按值传递和按引用传递 i深入理解变量 i掌握包装类 i理解类型转换 i理解Ja ...

  2. Java基础与提高干货系列——Java反射机制

    前言 今天介绍下Java的反射机制,以前我们获取一个类的实例都是使用new一个实例出来.那样太low了,今天跟我一起来学习学习一种更加高大上的方式来实现. 正文 Java反射机制定义 Java反射机制 ...

  3. Java从零开始学三十六(JAVA IO- 字符流)

    一.字符流 BufferedReader:BufferedReader是从缓冲区之中读取内容,所有的输入的字节数据都将放在缓冲区之中 BufferedWriter:把一批数据写入到缓冲区,当缓冲区区的 ...

  4. java基础(三):java面向对象OOP

    java面向对象OOP 基本概念 面向过程与面向对象 面向过程:关注代码实现的细节.复用性 面向对象:先把每个过程的代码实现细节整合到对象中,只要找到对象就能拥有对象身上所有的功能. 面向对象基于面向 ...

  5. java条件配置,三、使用JAVA必备条件—环境配置

    一.环境配置准备条件 1.1 下载JDK 1.1.1 jdk简介: JDK:包含SDK,JRE,全称:Java Development Kit,他为开发人员提供了JAVA的开发环境和运行环境: SDK ...

  6. JAVA学习(三):Java基础语法(变量、常量、数据类型、运算符与数据类型转换)...

    Java基础语法(变量.常量.数据类型.运算符与数据类型转换) 1.变量 Java中.用户能够通过指定数据类型和标识符来声明变量.其基本的语法为: DataType identifier; 或 Dat ...

  7. java基础总结(三十一)--利用java代码写出http请求的服务端与客户端代码

    来自https://www.cnblogs.com/Nouno/p/5719010.html java开发接口利用http协议传输数据 这个接口主要用来登录,java服务器提供一个接口,移动设备客户端 ...

  8. 温故而知新--Java基础(三):Java常用集合类(上)

    前言: 数组和集合的区别: 数组声明了器元素的类型,集合不需要声明. 数组创建之后大小固定,不能扩容,集合大小不固定,可以根据需要动态扩容,集合里提供更多的成员方法,满足更多的需求. 数组存放的数据类 ...

  9. java私塾 java篇_Java私塾跟我学系列——JAVA篇 五、

    五:Java如何做到让机器理解我们想要做的东西 用一个图来描述这个过程会比较容易理解: 1:编写代码 首先把我们想要计算机做的事情,通过Java表达出来,写成Java文件,这个过程就是 编写代码的过程 ...

  10. Java 9的误解和Java 10的愿望清单:Java影响者的全部访谈

    是时候消除那些Java 9的误解了 Java 9将在9月到达,即使我们已经准备好了也没有,但是在到达Java 9之前,仍有一些事情需要理解. 我们需要停止思考Maven在Java 9上不起作用,并且如 ...

最新文章

  1. Thrift在windows下的使用
  2. moss 与SAP iView web part 整合
  3. ios8 UITableView section不显示
  4. python三十五:pickle模块
  5. 【今日互联网大事儿】小米净化器出来了呢
  6. Html爱情表白动画
  7. 还在集什么五福,史上最惨锦鲤再次来袭!奖品堪比5年高考3年模拟!
  8. android打包规范包含第三方库aar,Android Studio 打包AAR和第三方静态库(示例代码)
  9. 数据科学和人工智能技术笔记 十七、聚类
  10. 计算机为什么要区别C盘,D盘,E盘等?
  11. Leviathan系列4-7
  12. Winform 窗体关闭事件
  13. 智能优化算法应用:基于麻雀搜索算法的积分计算 -附代码
  14. 数据库事务特征、数据库隔离级别,以及各级别数据库加锁情况(含实操)--read uncommitted篇...
  15. 电脑tf卡检测不到_电脑不认TF卡,有什么方法
  16. QTTabBar——Windows多功能标签软件
  17. Python函数调用的九大方法,鲜为人知
  18. 常微分和偏微分方程的区别是啥?
  19. 《剑指offter》
  20. 寒武纪加速平台(MLU200系列) 摸鱼指南(一)--- 基本概念及相关介绍

热门文章

  1. BZOJ2243[SDOI2011] 染色
  2. join为什么每个字符都分割了 js_2019JS必看面试题
  3. 不能bostype没有元数据异常_金蝶EAS - BOS工作笔记
  4. 千牛取消机器人自动回复_拼多多回复率低怎么办?
  5. 手机没信号突然无服务器,OPPO手机没信号怎么办?解决OPPO手机突然没信号的方法...
  6. 最快的 java 图像_java – 最快的性能过滤图像
  7. 整型数组 java_java创建一个整型数组,数组的大小由用户输入?
  8. 公钥 私钥_比特币私钥、公钥、钱包地址之间的关系
  9. Winform窗体验证登陆
  10. 关于变量声明的var,let,const