NIO基本操作
NIO是Java 4里面提供的新的API,目的是用来解决传统IO的问题
NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector(选择器)
Channel(通道)
通道:类似于流,但是可以异步读写数据(流只能同步读写),通道是双向的,(流是单向的),通道的数据总是要先读到一个buffer 或者 从一个buffer写入,即通道与buffer进行数据交互。
通道类型:
FileChannel:从文件中读写数据。
DatagramChannel:能通过UDP读写网络中的数据。
SocketChannel:能通过TCP读写网络中的数据。
ServerSocketChannel:可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。
通过使用FileChannel可以从文件读或者向文件写入数据;通过SocketChannel,以TCP来向网络连接的两端读写数据;通过ServerSocketChanel能够监听客户端发起的TCP连接,并为每个TCP连接创建一个新的SocketChannel来进行数据读写;通过DatagramChannel,以UDP协议来向网络连接的两端读写数据。
Buffer(缓冲区)
缓冲区 本质上是一块可以存储数据的内存,被封装成了buffer对象而已!
缓冲区类型:
ByteBuffer
MappedByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
常用方法:
allocate() - 分配一块缓冲区
put() - 向缓冲区写数据
get() - 向缓冲区读数据
filp() - 将缓冲区从写模式切换到读模式
clear() - 从读模式切换到写模式,不会清空数据,但后续写数据会覆盖原来的数据,即使有部分数据没有读,也会被遗忘;
compact() - 从读数据切换到写模式,数据不会被清空,会将所有未读的数据copy到缓冲区头部,后续写数据不会覆盖,而是在这些数据之后写数据
mark() - 对position做出标记,配合reset使用
reset() - 将position置为标记值
hasRemaining() - 判断是否还有可用数据
缓冲区的一些属性:
capacity - 缓冲区大小,无论是读模式还是写模式,此属性值不会变;
position - 写数据时,position表示当前写的位置,每写一个数据,会向下移动一个数据单元,初始为0;最大为capacity - 1切换到读模式时,position会被置为0,表示当前读的位置
limit - 写模式下,limit 相当于capacity 表示最多可以写多少数据,切换到读模式时,limit 等于原先的position,表示最多可以读多少数据。
Selector(选择器)
选择器:相当于一个观察者,用来监听通道感兴趣的事件,一个选择器可以绑定多个通道;
通道向选择器注册时,需要指定感兴趣的事件,选择器支持以下事件:
SelectionKey.OP_CONNECT
SelectionKey.OP_ACCEPT
SelectionKey.OP_READ
SelectionKey.OP_WRITE
如果你对不止一种事件感兴趣,那么可以用“位或”操作符将常量连接起来,如下:
int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;
通道向选择器注册时,会返回一个 SelectionKey对象,具有如下属性
interest集合
ready集合
Channel
Selector
附加的对象(可选)
用“位与”操作interest 集合和给定的SelectionKey常量,可以确定某个确定的事件是否在interest 集合中。
int interestSet = selectionKey.interestOps(); boolean isInterestedInAccept = interestSet & SelectionKey.OP_ACCEPT;
boolean isInterestedInConnect = interestSet & SelectionKey.OP_CONNECT;
boolean isInterestedInRead = interestSet & SelectionKey.OP_READ;
boolean isInterestedInWrite = interestSet & SelectionKey.OP_WRITE;
ready 集合是通道已经准备就绪的操作的集合。在一次选择(Selection)之后,你会首先访问这个ready set。Selection将在下一小节进行解释。可以这样访问ready集合:
int readySet = selectionKey.readyOps();
也可以使用以下四个方法获取已就绪事件,返回值为boolean:
selectionKey.isAcceptable();
selectionKey.isConnectable();
selectionKey.isReadable();
selectionKey.isWritable();
可以将一个对象或者更多信息附着到SelectionKey上,即记录在附加对象上,方法如下:
selectionKey.attach(theObject);
Object attachedObj = selectionKey.attachment();
可以通过选择器的select方法获取是否有就绪的通道;
int select()
int select(long timeout)
int selectNow()
返回值表示上次执行select之后,就绪通道的个数。
可以通过selectedKeySet获取已就绪的通道。返回值是SelectionKey 的集合,处理完相应的通道之后,需要removed 因为Selector不会自己removed
select阻塞后,可以用wakeup唤醒;执行wakeup时,如果没有阻塞的select 那么执行完wakeup后下一个执行select就会立即返回。
调用close() 方法关闭selector
传统IO和NIO简单例子
传统IO读取文件:
public static void ioRead() {
File file = new File("f:/io.txt");
InputStream in = null;
try {
in = new FileInputStream(file);
byte[] bytes = new byte[1024];
in.read(bytes);
System.out.println(new String(bytes)); } catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
NIO操作
public static void nioRead() {
RandomAccessFile aFile = null;
try {
aFile = new RandomAccessFile("F:/io.txt", "rw");
FileChannel fileChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024);
int bytesRead = fileChannel.read(buf);
System.out.println(bytesRead);
while (bytesRead != -1) {
buf.flip();
while (buf.hasRemaining()) {
System.out.print((char) buf.get());
}
buf.compact();
bytesRead = fileChannel.read(buf);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (aFile != null) {
aFile.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
NIO基本操作的更多相关文章
- Java IO系列之二:NIO基本操作
核心部分 NIO( New Input/ Output) , 引入了一种基于通道和缓冲区的 I/O 方式,NIO 是一种同步非阻塞的 IO 模型.同步是指线程不断轮询 IO 事件是否就绪,非阻塞是指 ...
- 撸基础篇系列,JAVA的NIO部分
前言:撸基础篇系列,避免每次都要从头开始看,写个自己的知识体系树 NIO 核心就是异步, 比如,复制文件,让操作系统去处理,等通知 BIO核心类 一,BIO NIO基本操作类 Bytebuffer 构 ...
- NIO缓冲区基本操作:rewind(),clear(),flip()
rewind() rewind()方法将position置0,清除mark,它的作用在于为提取Buffer的有效数据做准备. ByteBuffer byteBuf = ByteBuffer.alloc ...
- Java NIO教程 Selector
这次我们开讲非阻塞I/O中的Selector,它需要配合非阻塞的TCP和UDP来使用.首先我们先简单讲一下TCP和UDP的非阻塞通道. 非阻塞I/O通道 在上代码前我们先讲解一些最基本的知识.TCP和 ...
- Java NIO教程 文件系统
在NIO.2的文件系统中,Path是一切操作的基础.Path准确来说,代表着文件系统中的位置.可以代表一个目录(也就是通常所说的文件夹),也可以代表一个文件. 在新文件系统中,还有一个不得不说的就是F ...
- Java NIO中的读和写
一.概述 读和写是I/O的基本过程.从一个通道中读取只需创建一个缓冲区,然后让通道将数据读到这个缓冲区.写入的过程是创建一个缓冲区,用数据填充它,然后让通道用这些数据来执行写入操作. 二.从文件中读取 ...
- Java NIO入门
NIO入门 前段时间在公司里处理一些大的数据,并对其进行分词.提取关键字等.虽说任务基本完成了(效果也不是特别好),对于Java还没入门的我来说前前后后花了2周的时间,我自己也是醉了.当然也有涉及到机 ...
- java nio io模型
I/O模型 在开始NIO的学习之前,先对I/O的模型有一个理解,这对NIO的学习是绝对有好处的.我画一张图,简单表示一下数据从外部磁盘向运行中进程的内存区域移动的过程: 这张图片明显忽略了很多细节,只 ...
- Java NIO 内存映射文件
Java NIO 内存映射文件 @author ixenos 文件操作的四大方法 前提:内存的访问速度比磁盘高几个数量级,但是基本的IO操作是直接调用native方法获得驱动和磁盘交互的,IO速度限制 ...
随机推荐
- ELF文件加载与动态链接(二)
GOT应该保存的是puts函数的绝对虚地址,这里为什么保存的却是puts@plt的第二条指令呢? 原来“解释器”将动态库载入内存后,并没有直接将函数地址更新到GOT表中,而是在函数第一次被调用时,才会 ...
- linux管道命令之head与tail
常常会遇到这样的情况: 1.我训练一个模型需要用到很多图片,这些图片都在一个文件夹下面,但是我想仅仅拷贝个一两张看一下图片的质量怎么样? 2.文件夹下有各种各样的数据,数目非常庞大,我想看一下文件夹下 ...
- poj 2387——单源最短路权值大于0
因为之前做过这个题.所以这次知道这道题有重边.这次dijkstra的写法加入了优先队列的优化 优先队列 结构体从小到大顺序的两种重载运算符的方式 bool operator <(const Ti ...
- 20155219 2016-2017-2 《Java程序设计》第9周学习总结
20155219 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 JDBC入门 JDBC简介 1.JDBC是java联机数据库的标准规范,它定义了一组标准类与 ...
- Flutter,H5,React Native
Flutter介绍 - Flutter,H5,React Native之间的对比 Flutter介绍 Flutter是Google推出的开源移动应用开发框架.开发者可以通过开发一套代码同时运行在i ...
- Echarts全解注释
coordinate-geo.js文件为地理坐标系的配置参数 mytextStyle={ color:"#333",//文字颜色 fontStyle:"normal&qu ...
- webpack中hash、chunkhash、contenthash区别
webpack中对于输出文件名可以有三种hash值: 1. hash 2. chunkhash 3. contenthash 这三者有什么区别呢? hash 如果都使用hash的话,因为这是工程级别的 ...
- Mongo 3.6.1版本Sharding集群配置
Mongo低版本和高版本的sharding集群配置,细节不太一样.目前网上的配置文档大都是针对低版本的.本人在配置3.6.1版本的mongosharding集群的过程中,碰到不少问题,官方文档没有直观 ...
- hive GenericUDF1
和UDF相比,通用GDF(GenericUDF)支持复杂类型(比如List,struct等)的输入和输出. 下面来看一个小示例. Hive中whereme表中包含若干人的行程如下: A 2 ...
- S老师 背包系统 装备系统 锻造系统 学习
Inventory using UnityEngine; using System.Collections; using System.Collections.Generic; using Syste ...