欢迎浏览我的博客 获得更多精彩文章
https://boyn.top
Java NIO 教程 (二) 通道
NIO中的通道有点像IO中的流式对象,但是又有一些不同:
- 在一个通道中,你既能够读,也能够写.流式对象通常是单向的
- 通道支持异步读写
- 通道永远与缓冲区绑定(从缓冲区读入,写入缓冲区)
通道的实现
以下是NIO中最重要的通道实现
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
FileChannel可以从文件中读入数据,也可以向文件中写入数据
DatagramChannel能够读写通过UDP传输的网络IO
SocketChannel能够读写通过TCP传输的网络IO
ServerSocketChannel能够像web服务器一样,监听传入的TCP连接.每个进入的TCP连接都会创建一个SocketChannel
基本的通道示例
package CoreJava.NIO;
/*
Author: Boyn
Date: 2019/6/3
*/
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class BasicFileChannelTest {
public static void main(String[] args) throws Exception{
RandomAccessFile aFile = new RandomAccessFile("data\\nio-data.txt", "rw");
//读入nio-data.txt中的值,后面的一个参数表示权限控制(rw是读写 read & write)
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);
//声明一个大小为48byte的缓冲区
int bytesRead = inChannel.read(buf);
while (bytesRead != -1) {
System.out.println("Read " + bytesRead);
buf.flip();//重要方法
while(buf.hasRemaining()){
System.out.print((char) buf.get());
}
buf.clear();//重要方法
bytesRead = inChannel.read(buf);
}
aFile.close();
}
}
译者的话:
在这个类中,line 22中的flip()方法和clear()是buffer中十分重要的一个方法,因为它涉及到buffer的底层结构与能够同时支持读写的功能
缓冲器的底层是一个数组,他在数组上提供了一个内部统计机制,这个机制中,最重要的有三个状态变量(理解为指针),分别是
- position:指定下一个将要被写入或者读取的元素的索引,
- limit:指定了还有多少数据需要取出,或者多少数据可以读入
- capacity:初始化时指定的容量,永远不变
在初始化一个缓冲区时,设置了capacity后,limit设置为capacity,position设置为0.
当我们写入了一些数据后(假设读入数据byte<limit),position的位置会向前.
当我们需要从这个缓冲区中取出数据时,首先需要调用flip()方法,根据官方文档
Flips this buffer. The limit is set to the current position and then the position is set to zero. If the mark is defined then it is discarded.
After a sequence of channel-read or put operations, invoke this method to prepare for a sequence of channel-write or relative get operations. For example:
buf.put(magic); // Prepend header in.read(buf); // Read data into rest of buffer buf.flip(); // Flip buffer out.write(buf); // Write header + data to channel
This method is often used in conjunction with the
compact
method when transferring data from one place to another.
flip()方法会将当前position的位置赋给limit,而将position设置为0,然后从0,也就是数据写入的地方开始读取.
那么,clear()方法的作用也就显而易见了,它会将这三个量进行重置,恢复其在初始化时的状态(limit,capacity在末端,position在头部)