今天來談一談NIO中的Channel,上一篇文章介紹了Buffer,有了Buffer還須要有一個通道來處理Buffer。它就是今天咱們要學習的Channel。按照字面理解,它就是一個通道,能夠從通道中讀數據,也能夠把數據寫入到通道中。git
Channel能夠分爲幾大類github
FileChannel比較簡單,主要用於文件操做。在使用FileChannel以前,須要先打開它。FileChannel是不能設置非阻塞的,咱們能夠經過RandomAccessFile
來獲取一個FileChannel的對象RandomAccessFile
的getChannel()
方法bash
public final FileChannel getChannel() {
synchronized (this) {
if (channel == null) {
channel = FileChannelImpl.open(fd, path, true, rw, this);
}
return channel;
}
}
複製代碼
有了FileChannel就能夠對文件進行讀寫了,咱們分別看一下讀寫的代碼。微信
首先把文件中的數據從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());
}
複製代碼
首先把要寫入的內容放入buffer裏,而後經過channel把buffer中的數據寫入到文件中,當咱們再查看文件的時候,就有寫入以後的內容了,代碼以下:socket
String str = " is best";
buffer.clear();
buffer.put(str.getBytes());
buffer.flip();
// 從buffer中讀出來,經過channel寫入到文件中
while (buffer.hasRemaining()) {
fileChannel.write(buffer);
}
複製代碼
使用完channel後關閉channel。學習
fileChannel.close();
複製代碼
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,使用UDP協議來進行傳輸。因爲不須要創建鏈接,其實沒有客戶端服務端的概念,爲了便於理解,咱們定義其中一端爲客戶端,一端爲服務端。
打開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());
}
複製代碼