使用NIO主要就是爲了提升IO的速度html
從文件中讀取
與傳統IO不一樣的是,使用NIO從文件中讀取主要分爲三步:
(1)從FileInputStream中獲取channel;java
FileInputStream fin = new FileInputStream( "readandshow.txt" ); FileChannel fc = fin.getChannel();
(2)建立buffer;數組
ByteBuffer buffer = ByteBuffer.allocate( 1024 );
(3)將數據從channel讀到buffer中。服務器
fc.read( buffer );
寫入文件
相似的,利用NIO寫入文件也分爲三步:
(1)從FileInputStream中獲取channel;網絡
FileOutputStream fout = new FileOutputStream( "writesomebytes.txt" ); FileChannel fc = fout.getChannel();
(2)建立一個緩衝區並在其中放入一些數據;函數
ByteBuffer buffer = ByteBuffer.allocate( 1024 ); for (int i=0; i<message.length; ++i) { buffer.put( message[i] ); //從message數組中取出放入buffer } buffer.flip(); //將buffer由寫模式切換爲讀模式
(3)將數據從buffer寫到通道中。學習
fc.write( buffer );
public final Buffer flip() { limit = position; position = 0; mark = -1; return this; }
這裏能夠注意到limit,position和mark三個變量
(1) capacity:代表能夠儲存在緩衝區中的最大數據容量。
(2) position:下一個可插入的位置(寫buffer時)或者下一個可讀的位置(讀buffer時)。
(3) limit:最多能寫多少數據(寫buffer時,至關於capacity),能夠讀多少數據(在從通道讀入緩衝區時)。
(4) mark:標記,記錄當前position的位置,能夠經過reset()恢復到mark的位置。大數據
Selector selector = Selector.open();
this
channel.configureBlocking(false);
//使用selector必須保證channel是非阻塞的模式SelectionKey key = channel.register(selector, Selectionkey.OP_READ);
注意register的第二個參數表示對選擇器對什麼事件感興趣。
而返回值記錄了包括channel,buffer,interest集合和ready集合等。spa
示例程序
Selector selector = Selector.open(); //開啓選擇器 channel.configureBlocking(false); //非阻塞模式 SelectionKey key = channel.register(selector, SelectionKey.OP_READ);//註冊 while(true) { int readyChannels = selector.select(); //選擇通道 if(readyChannels == 0) continue; Set selectedKeys = selector.selectedKeys(); //獲取通道 Iterator keyIterator = selectedKeys.iterator(); while(keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if(key.isAcceptable()) { // a connection was accepted by a ServerSocketChannel. } else if (key.isConnectable()) { // a connection was established with a remote server. } else if (key.isReadable()) { // a channel is ready for reading } else if (key.isWritable()) { // a channel is ready for writing } keyIterator.remove(); //須要本身移除處理完的通道 } }
NIO具有必定的優勢,但並非說傳統IO就一無可取
(1)在處理數據上,若是遇到逐行處理的狀況,如:
Name: Anna Age: 25 Email: anna@mailserver.com Phone: 1234567890
傳統的IO能夠這樣寫:
BufferedReader reader = new BufferedReader(new InputStreamReader(input)); String nameLine = reader.readLine(); String ageLine = reader.readLine(); String emailLine = reader.readLine(); String phoneLine = reader.readLine();
但若是使用NIO:
ByteBuffer buffer = ByteBuffer.allocate(48); int bytesRead = inChannel.read(buffer);
你就不知道緩衝區內是否恰好是一行數據,這樣處理起來會比較麻煩。
(2)若是須要管理同時打開的成千上萬個鏈接,這些鏈接每次只是發送少許的數據,例如聊天服務器,實現NIO的服務器多是一個優點。
若是你須要維持許多打開的鏈接到其餘計算機上,如P2P網絡中,使用一個單獨的線程來管理你全部出站鏈接,多是一個優點。
但若是你有少許的鏈接使用很是高的帶寬,一次發送大量的數據,也許典型的IO服務器實現可能很是契合。
學習參考:http://ifeve.com/java-nio-all/ Java NIO 系列教程
https://www.ibm.com/developer... NIO入門