NIO 详解
Posted loveer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NIO 详解相关的知识,希望对你有一定的参考价值。
同步非阻塞
NIO之所以是同步,是因为它的accept
read
write
方法的内核I/O操作
都会阻塞当前线程
Channel(通道)
Channel(通道):
Channel是一个对象,可以通过它读取和写入数据。可以把它看做是IO中的流,不同的是:
Channel是双向的(NIO面向缓冲区,双向传输),既可以读又可以写,而流是单向的(传统IO操作是面向流,单向传输)
Channel可以进行异步的读写
对Channel的读写必须通过buffer对象
buffer负责存储数据,channel负责传输数据
在Java NIO中的Channel主要有如下几种类型:
FileChannel:从文件读取数据的
DatagramChannel:读写UDP网络协议数据
SocketChannel:读写TCP网络协议数据
ServerSocketChannel:可以监听TCP连接
Buffer(缓冲区)
Buffer是一个对象:
它包含一些要写入或者读取Stream对象的。用于读写操作(put()存,get()取)。
它包含四个属性:
capacity(总容量)
limit(当前可用容量)
position(正在操作数据的位置)
mark(标记当前position,可通过reset()恢复mark位置)
在NIO中,Buffer实质上是一个数组,通常是一个字节数据,但也可以是其他类型的数组。
使用 Buffer 读写数据一般遵循以下四个步骤:
1.写入数据到 Buffer;
2.调用 flip() 方法;
3.从 Buffer 中读取数据;
4.调用 clear() 方法或者 compact() 方法。
当向 Buffer 写入数据时,Buffer 会记录下写了多少数据。
一旦要读取数据,需要通过 flip() 方法将 Buffer 从写模式切换到读模式。
在读模式下,可以读取之前写入到 Buffer 的所有数据。
一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。有两种方式能清空缓冲区:
调用 clear() 或 compact() 方法。
clear() 方法会清空整个缓冲区。
compact() 方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。
Buffer主要有如下几种:
ByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
简单应用
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class CopyFile {
public static void copyFile(String src, String dst) throws IOException {
//源文件输入流
FileInputStream fi = new FileInputStream(new File(src));
//目标文件输出流
FileOutputStream fo = new FileOutputStream(new File(dst));
//获得传输通道channel
FileChannel inChannel = fi.getChannel();
FileChannel outChannel = fo.getChannel();
//获得容器buffer
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (true) {
//判断是否读完文件:阻塞式
int eof = inChannel.read(buffer);
if (eof == -1) {
break;
}
//重设一下buffer的limit=position,position=0
buffer.flip();
//开始写
outChannel.write(buffer);
//写完要重置buffer,重设position=0,limit=capacity
buffer.clear();
}
inChannel.close();
outChannel.close();
fi.close();
fo.close();
}
}
以上是关于NIO 详解的主要内容,如果未能解决你的问题,请参考以下文章
Java网络编程和NIO详解8:浅析mmap和Direct Buffer