Java NIO 教程 (二) 通道

5 篇文章 0 订阅
4 篇文章 0 订阅

欢迎浏览我的博客 获得更多精彩文章
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在头部)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值