Java NIO的通道類似流,但又有些不同:
- 既可以從通道中讀取數(shù)據(jù),又可以寫數(shù)據(jù)到通道妻柒。但流的讀寫通常是單向的。
- 通道可以異步地讀寫耘分。
- 通道中的數(shù)據(jù)總是要先讀到一個(gè)Buffer举塔,或者總是要從一個(gè)Buffer中寫入。
正如上面所說求泰,從通道讀取數(shù)據(jù)到緩沖區(qū)名挥,從緩沖區(qū)寫入數(shù)據(jù)到通道。如下圖所示:
Channel的實(shí)現(xiàn)
這些是Java NIO中最重要的通道的實(shí)現(xiàn):
FileChannel
DatagramChannel
SocketChannel
ServerSocketChannel
FileChannel 從文件中讀寫數(shù)據(jù)遗遵。
DatagramChannel 能通過UDP讀寫網(wǎng)絡(luò)中的數(shù)據(jù)老赤。
SocketChannel 能通過TCP讀寫網(wǎng)絡(luò)中的數(shù)據(jù)。
ServerSocketChannel可以監(jiān)聽新進(jìn)來的TCP連接枉氮,像Web服務(wù)器那樣志衍。對(duì)每一個(gè)新進(jìn)來的連接都會(huì)創(chuàng)建一個(gè)SocketChannel。
基本的 Channel 示例
下面是一個(gè)使用FileChannel讀取數(shù)據(jù)到Buffer中的示例:
public class Main {
public static void main(String[] args) throws IOException {
System.out.println("Hello World!");
RandomAccessFile aFile = new RandomAccessFile("nio-data.txt","rw");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);
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);
}
}
}
結(jié)果:
注意 buf.flip() 的調(diào)用聊替,首先讀取數(shù)據(jù)到Buffer楼肪,然后反轉(zhuǎn)Buffer,接著再從Buffer中讀取數(shù)據(jù)。下一節(jié)會(huì)深入講解Buffer的更多細(xì)節(jié)惹悄。