NIO学习笔记

Posted hejinsheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NIO学习笔记相关的知识,希望对你有一定的参考价值。

NIO区别于IO,是同步非阻塞的。nio直接使用native函数库,直接分配对外内存,通过DirectByteBuffer对象作为这块内存的引用操作,避免了数据在java堆和对外内存间来回复制。

 

主要组件:

Channel  通道,文件数据首先存在于channel中 可通过FileInputStream.getChannel()获取到channel

Buffer   缓冲区,数据可以从通道读入缓冲区,也可以将数据从缓冲区写到通道中

Select   用于管理一个或多个通道

 

nio读取文件示例

 1 public class TestChannel {
 2     public static void main(String[] args) throws IOException {
 3         //读取到文件
 4         RandomAccessFile f = new RandomAccessFile("C:\\test-nio.txt", "rw");
 5         //获取channel
 6         FileChannel channel = f.getChannel();
 7         //分配缓存大小
 8         ByteBuffer buffer = ByteBuffer.allocate(1024);
 9         //从channel中读取数据循环读取到缓存中
10         int bytesRead = channel.read(buffer);
11         while (bytesRead != -1){
12             System.out.println("before flip:"+buffer);
13             //切换为读模式,反转pos为0,使下一步get从0开始
14             buffer.flip();
15             System.out.println("after flip:"+buffer);
16             while (buffer.hasRemaining()){
17                 System.out.print((char)buffer.get());
18             }
19             //上一步打印完成后清除缓存内数据,使缓冲区可以再次被写入
20             buffer.clear();
21             System.out.println("\nafter clear:"+buffer);
22 
23             bytesRead = channel.read(buffer);
24         }
25         //关闭通道
26         channel.close();29     }
30 }

 

几个方法说明:

flip()  将buffer从写模式切换为读模式,是pos=0 limit=“写模式时最后的pos“。limit表示此缓冲区中最多可以读取的字节数

clear() 清空缓冲区,使pos=0 limit=capaticy

compact()   将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面。注意和clear区分,clear不处理未读数据,直接清空

rewind()      将position设回0,所以你可以重读Buffer中的所有数据。limit保持不变,仍然表示能从Buffer中读取多少

mark()/reset()   通过调用Buffer.mark()方法,可以标记Buffer中的一个特定position。之后可以通过调用Buffer.reset()方法恢复到这个position

 

 

scatter和gather:分散和聚合

 1 public class TestScatterGather {
 2     public static void main(String[] args) throws IOException {
 3         RandomAccessFile raf = new RandomAccessFile("c:/test-nio.txt", "rw");
 4         FileChannel channel = raf.getChannel();
 5 
 6         ByteBuffer header = ByteBuffer.allocate(10);
 7         ByteBuffer body = ByteBuffer.allocate(200);
 8 
 9         ByteBuffer[] bufferArr = {header,body};
10         long x = channel.read(bufferArr);
11 
12         header.flip();
13         while (header.hasRemaining()){
14             System.out.print((char)header.get());
15         }
16         header.clear();
17 
18         System.out.println("============");
19 
20         body.flip();
21         while (body.hasRemaining()){
22             System.out.print((char)body.get());
23         }
24         body.clear();
25     }
26 }

 

以上是关于NIO学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

Java NIO学习笔记八 DatagramChannel

java NIO学习笔记上(尚硅谷)

学习笔记:python3,代码片段(2017)

nio学习笔记

BIO NIO AIO 学习笔记

NIO学习笔记