NIO核心组件之Channel


NIO概述

Java NIO(New IO 或 Non Blocking IO)是从 Java 1.4 版本开始引入的一个新的IO API,可以替代标准的 Java IO API。NIO 支持面向缓冲区的、基于通道的 IO 操作。NIO 将以更加高效的方式进行文件的读写操作。
Java NIO有三大核心组件:Channel、Buffer和Selectors。


1、Channel是什么?

Channel可译为“通道”,Channel 和 IO 中的Stream(流)是差不多一个等级的。只不过 Stream 是单向的,而Channel是全双工的,通过缓冲区Buffer来进行读写操作。 NIO 中的 Channel 的主要实现有:FileChannel、DatagramChannel、SocketChannel 和 ServerSocketChannel,分别可以对应文件 IO、UDP 和 TCP(Server 和 Client)。

2、Channel的主要实现

2.1 FileChannel

FileChannel 顾名思义是从文件中读写数据的Channel。

(1)借助RandomAccessFile创建一个FileChannel
	String fileName = "e://001.txt";//文件路径
    RandomAccessFile aFile =
            new RandomAccessFile(fileName,"rw");
    FileChannel channel = aFile.getChannel();
(2)Channel必须借助缓冲区来进行数据交换,因此需要创建一个Buffer
	ByteBuffer buf = ByteBuffer.allocate(1024);
    //读数据到buffer中
    int bytesRead = channel.read(buf);
(3)进行读写操作
	while(bytesRead != -1){
        System.out.println("读取了"+bytesRead);
		buf.flip();//调用buffer反转读写模式
        while(buf.hasRemaining()){//如果buffer中还有剩余
            System.out.println((char) buf.get());
        }
        buf.clear();//清除缓冲区内容
        bytesRead = channel.read(buf);
    }
    //aFile.close();
    System.out.println("读数据结束!");

	//向FileChannel中写数据
    if(buf.hasRemaining()) buf.clear();
    String a = "hello Java NIO!";
    //向缓冲区写入数据
    buf.put(a.getBytes());
    buf.flip();
	//最后由FileChannel将缓冲区的数据写入
    while(buf.hasRemaining()){
        channel.write(buf);
    }
    channel.close();
    System.out.println("写数据完成!");

2.2 ServerSocketChannel

ServerSocketChannel 是一个基于通道的 socket 监听器。它同我们所熟悉的java.net.ServerSocket 执行相同的任务,不过它增加了通道语义,因此能够在非阻塞模式下运行。

	ByteBuffer byteBuffer = ByteBuffer.wrap("Hello java nio!".getBytes());
	ServerSocketChannel ssc = ServerSocketChannel.open();
	//取出对等的 socket,绑定到一个端口进行监听
	ssc.socket().bind(new InetSocketAddress(port));
	
 	//设置非阻塞模式
	ssc.configureBlocking(false);

2.3 SocketChannel

(1)创建一个SocketChannel

SocketChannel socketChannel = SocketChannel.open(
new InetSocketAddress("www.baidu.com", 80));

(2)连接校验

	socketChannel.isOpen(); // 测试 SocketChannel 是否为 open 状态
	socketChannel.isConnected(); //测试 SocketChannel 是否已经被连接
	socketChannel.isConnectionPending(); //测试 SocketChannel 是否正在进行连接
	socketChannel.finishConnect(); //校验正在进行套接字连接的 SocketChannel是否已经完成连接

(2)读写

	SocketChannel socketChannel = SocketChannel.open(
 		new InetSocketAddress("www.baidu.com", 80));
 	socketChannel.configureBlocking(false);//设置 SocketChannel 的读写模式非阻塞
	ByteBuffer byteBuffer = ByteBuffer.allocate(16);
	socketChannel.read(byteBuffer);
	socketChannel.close();
	System.out.println("read over");

2.4 DatagramChannel

DatagramChannel 是无连接的,每个数据报(datagram)都是一个自包含的实体,拥有它自己的目的地址及不依赖其他数据报的数据负载。与面向流的的 socket 不同,DatagramChannel 可以发送单独的数据报给不同的目的地址。同样,DatagramChannel 对象也可以接收来自任意地址的数据包。每个到达的数据报都含有关于它来自何处的信息(源地址)。 代码示例:
@Test
public void sendDatagram() throws IOException, InterruptedException {
	DatagramChannel sendChannel= DatagramChannel.open();
	InetSocketAddress sendAddress= new InetSocketAddress("127.0.0.1", 9999);
	while (true) {
		sendChannel.send(ByteBuffer.wrap("发包".getBytes("UTF-8")), sendAddress);
		System.out.println("发包端发包");
		Thread.sleep(1000);
	}
}

总结

以上就是关于NIO组件之一Channel的部分,本文只是简要介绍了Channel的一些主要实现及其使用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值