Java NIO之Channel

今天来谈一谈NIO中的Channel,上一篇文章介绍了Buffer,有了Buffer还须要有一个通道来处理Buffer。它就是今天咱们要学习的Channel。按照字面理解,它就是一个通道,能够从通道中读数据,也能够把数据写入到通道中。git

Channel能够分为几大类github

  • FileChannel(文件操做)
  • SocketChannel(客户端TCP操做)
  • ServerSocketChannel(服务端TCP操做)
  • DatagramChannel(UDP操做)

FileChannel

FileChannel比较简单,主要用于文件操做。在使用FileChannel以前,须要先打开它。FileChannel是不能设置非阻塞的,咱们能够经过RandomAccessFile来获取一个FileChannel的对象RandomAccessFilegetChannel()方法bash

public final FileChannel getChannel() {
    synchronized (this) {
        if (channel == null) {
            channel = FileChannelImpl.open(fd, path, true, rw, this);
        }
        return channel;
    }
}
复制代码

有了FileChannel就能够对文件进行读写了,咱们分别看一下读写的代码。微信

read

首先把文件中的数据从channel中读出来,而后写入到咱们分配的buffer里,而后再把buffer中的数据打印出来,代码以下:dom

ByteBuffer buffer = ByteBuffer.allocate(100);
// fileChannel中读出来,写到buffer中
int read = fileChannel.read(buffer);
buffer.flip();
while (buffer.hasRemaining()) {
	System.out.print((char) buffer.get());
}
复制代码

write

首先把要写入的内容放入buffer里,而后经过channel把buffer中的数据写入到文件中,当咱们再查看文件的时候,就有写入以后的内容了,代码以下:socket

String str = " is best";
buffer.clear();
buffer.put(str.getBytes());
buffer.flip();
// 从buffer中读出来,经过channel写入到文件中
while (buffer.hasRemaining()) {
	fileChannel.write(buffer);
}
复制代码

close

使用完channel后关闭channel。学习

fileChannel.close();
复制代码

SocketChannel&ServerSocketChannel

SocketChannel和ServerSocketChannel主要用于TCP链接。SocketChannel用于客户端,ServerSocketChannel用于服务端,客户端和服务端通讯以前首先要创建链接。ui

创建链接

客户端

客户端创建链接的过程,首先打开SocketChannel,而后链接到服务端,代码以下:this

SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("127.0.0.1", 8000));
复制代码

服务端

服务端首先打开ServerSocketChannel,而后绑定一个端口,代码以下:spa

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(8000));
复制代码

发送接收数据

客户端

链接创建成功以后,客户端就能够给服务端发送数据了,和FileChannel同样,首先要把数据放到buffer中,而后再写到channel里。

//链接是否创建成功
boolean isConnect = socketChannel.isConnected();

ByteBuffer buffer = ByteBuffer.allocate(128);
buffer.clear();
buffer.put(("qiwoo").getBytes());

buffer.flip();
while (buffer.hasRemaining()) {
	socketChannel.write(buffer);
}

复制代码

服务端

服务端ServerSocketChannel收到链接请求时,返回一个SocketChannel对象。而后就能够把数据从channel中读出来,而后写入到buffer里。

SocketChannel socketChannel = serverSocketChannel.accept();

ByteBuffer buffer = ByteBuffer.allocate(128);
socketChannel.read(buffer);

buffer.flip();

while (buffer.hasRemaining()) {
	System.out.println((char) buffer.get());
}
复制代码

DatagramChannel

DatagramChannel,使用UDP协议来进行传输。因为不须要创建链接,其实没有客户端服务端的概念,为了便于理解,咱们定义其中一端为客户端,一端为服务端。

Bind端口

客户端

打开DatagramChannel,而后绑定一个端口

DatagramChannel datagramChannel = DatagramChannel.open();
datagramChannel.socket().bind(new InetSocketAddress(8888));
复制代码

服务端

打开DatagramChannel,而后绑定一个端口

DatagramChannel datagramChannel = DatagramChannel.open();
datagramChannel.socket().bind(new InetSocketAddress(8889));
复制代码

发送接收数据

发送和接收数据也比较简单,代码以下:

客户端

ByteBuffer buffer = ByteBuffer.allocate(100);

buffer.put("qiwoo".getBytes());
buffer.flip();

InetAddress address = InetAddress.getLocalHost();
datagramChannel.send(buffer, new InetSocketAddress(address, 8889));
复制代码

服务端

ByteBuffer buffer = ByteBuffer.allocate(100);
buffer.clear();
datagramChannel.receive(buffer);
buffer.flip();
while (buffer.hasRemaining()) {
	System.out.print((char) buffer.get());
}
复制代码

本文demo

关注微信公众号,最新技术干货实时推送

image
相关文章
相关标签/搜索