在Java NIO中,通道是用於在實體和位元組緩衝區之間有效傳輸數據的介質。它從一個實體讀取數據,並將其放在緩衝區塊中以供消費。
通道作為Java NIO提供的網關來訪問I/O機制。 通常,通道與操作系統檔描述符具有一對一關係,用於提供平臺獨立操作功能。
讓我們來看看java.nio.channels
類的層次結構:
上述通道可以用於阻塞或非阻塞模式,但是我們主要關注在非阻塞模式下使用通道。
NIO通道基礎
通道實現是使用本地代碼執行實際工作。通道介面允許我們以便攜和受控的方式訪問低級I/O服務。
在層次結構的頂部,通道介面如下所示:
package java.nio.channels;
public interface Channel{
public boolean isclose();
public void Open() throws IOException;
}
正如在上述通道介面中看到的,所有通道只有兩個常用操作:
- 檢查通道是否關閉(
isclose()
) - 打開關閉通道(
close()
)
通道實現
在Java NIO中,主要使用的通道如下:
- FileChannel:檔通道用於從檔讀取數據。它只能通過調用
getChannel()
方法來創建對象。不能直接創建FileChannel
對象。
下麵是一個創建FileChannel
對象的例子:FileInputStream fis = new FileInputStream("D:\\file-read.txt"); // Path of Input text file ReadableByteChannel rbc = fis.getChannel();
- DatagramChannel:數據報通道可以通過UDP(用戶數據報協議)通過網路讀取和寫入數據。它使用工廠方法來創建新對象。
下麵是打開DatagramChannel
的語法:
用於關閉DatagramChannel ch = DatagramChannel.open();
DatagramChannel
的語法:DatagramChannel ch = DatagramChannel.close();
- SocketChannel:數據報通道可以通過TCP(傳輸控制協議)通過網路讀取和寫入數據。 它還使用工廠方法來創建新對象。
用於打開SocketChannel
的語法:
用於關閉SocketChannel ch = SocketChannel.open(); ch.connect(new InetSocketAddress("somehost", someport));
SocketChannel
的語法:SocketChannel ch = SocketChannel.close(); ch.connect(new InetSocketAddress("somehost", someport));
- ServerSocketChannel:
ServerSocketChannel
允許用戶監聽傳入的TCP連接,與Web伺服器相同。對於每個傳入連接,都會為連接創建一個SocketChannel
。
下麵是打開ServerSocketChannel
的語法:
下麵是關閉ServerSocketChannel ch = ServerSocketChannel.open(); ch.socket().bind (new InetSocketAddress (somelocalport));
ServerSocketChannel
的語法:ServerSocketChannel ch = ServerSocketChannel.close(); ch.socket().bind (new InetSocketAddress (somelocalport));
基本通道示例
下麵來看看如何將數據從一個通道複製到另一個通道或從一個檔複製到另一個檔的示例:
package com.zaixian;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
public class ChannelDemo {
public static void main(String args[]) throws IOException {
String relativelyPath = System.getProperty("user.dir");
FileInputStream input = new FileInputStream(relativelyPath + "/testin.txt");
ReadableByteChannel source = input.getChannel();
FileOutputStream output = new FileOutputStream(relativelyPath + "/testout.txt");
WritableByteChannel destination = output.getChannel();
copyData(source, destination);
source.close();
destination.close();
System.out.println("Copy Data finished.");
}
private static void copyData(ReadableByteChannel src, WritableByteChannel dest) throws IOException {
ByteBuffer buffer = ByteBuffer.allocateDirect(20 * 1024);
while (src.read(buffer) != -1) {
// The buffer is used to drained
buffer.flip();
// keep sure that buffer was fully drained
while (buffer.hasRemaining()) {
dest.write(buffer);
}
buffer.clear(); // Now the buffer is empty, ready for the filling
}
}
}
執行上面示例代碼,得到以下結果:
Copy Data finished.
上述程式將文本檔filein.txt
的內容複製到另一個文本檔fileout.txt
。
上一篇:
Java IO與NIO比較
下一篇:
Java NIO緩衝區