Java NIO使用及原理分析(1-4)(轉)

轉載的原文章也找不到!從如下博客中找到
http://blog.csdn.net/wuxianglong/article/details/6604817

轉載自:李會軍•寧靜致遠java

最近因爲工做關係要作一些Java方面的開發,其中最重要的一塊就是Java NIO(New I/O),儘管很早之前瞭解過一些,但並無認真去看過它的實現原理,也沒有機會在工做中使用,此次也好從新研究一下,順便寫點東西,就當是本身學習 Java NIO的筆記了。本文爲NIO使用及原理分析的第一篇,將會介紹NIO中幾個重要的概念。mysql

在Java1.4以前的I/O系統中,提供的都是面向流的I/O系統,系統一次一個字節地處理數據,一個輸入流產生一個字節的數據,一個輸出流消費一個字節的數據,面向流的I/O速度很是慢,而在Java 1.4中推出了NIO,這是一個面向塊的I/O系統,系統以塊的方式處理處理,每個操做在一步中產生或者消費一個數據庫,按塊處理要比按字節處理數據快的多。web

在NIO中有幾個核心對象須要掌握:緩衝區(Buffer)、通道(Channel)、選擇器(Selector)。sql

緩衝區Buffer數據庫

緩衝區其實是一個容器對象,更直接的說,其實就是一個數組,在NIO庫中,全部數據都是用緩衝區處理的。在讀取數據時,它是直接讀到緩衝區中的; 在寫入數據時,它也是寫入到緩衝區中的;任什麼時候候訪問 NIO 中的數據,都是將它放到緩衝區中。而在面向流I/O系統中,全部數據都是直接寫入或者直接將數據讀取到Stream對象中。數組

在NIO中,全部的緩衝區類型都繼承於抽象類Buffer,最經常使用的就是ByteBuffer,對於Java中的基本類型,基本都有一個具體Buffer類型與之相對應,它們之間的繼承關係以下圖所示:

下面是一個簡單的使用IntBuffer的例子:app

[java]   view plain  copy
 print ?
  1. import java.nio.IntBuffer;  
  2.   
  3. public class TestIntBuffer {  
  4.     public static void main(String[] args) {  
  5.         // 分配新的int緩衝區,參數爲緩衝區容量  
  6.         // 新緩衝區的當前位置將爲零,其界限(限制位置)將爲其容量。它將具備一個底層實現數組,其數組偏移量將爲零。  
  7.         IntBuffer buffer = IntBuffer.allocate(8);  
  8.   
  9.         for (int i = 0; i < buffer.capacity(); ++i) {  
  10.             int j = 2 * (i + 1);  
  11.             // 將給定整數寫入此緩衝區的當前位置,當前位置遞增  
  12.             buffer.put(j);  
  13.         }  
  14.   
  15.         // 重設此緩衝區,將限制設置爲當前位置,而後將當前位置設置爲0  
  16.         buffer.flip();  
  17.   
  18.         // 查看在當前位置和限制位置之間是否有元素  
  19.         while (buffer.hasRemaining()) {  
  20.             // 讀取此緩衝區當前位置的整數,而後當前位置遞增  
  21.             int j = buffer.get();  
  22.             System.out.print(j + "  ");  
  23.         }  
  24.   
  25.     }  
  26.   
  27. }  
運行後能夠看到:

在後面咱們還會繼續分析Buffer對象,以及它的幾個重要的屬性。ide

通道Channeloop

通道是一個對象,經過它能夠讀取和寫入數據,固然了全部數據都經過Buffer對象來處理。咱們永遠不會將字節直接寫入通道中,相反是將數據寫入包含一個或者多個字節的緩衝區。一樣不會直接從通道中讀取字節,而是將數據從通道讀入緩衝區,再從緩衝區獲取這個字節。post

在NIO中,提供了多種通道對象,而全部的通道對象都實現了Channel接口。它們之間的繼承關係以下圖所示:

使用NIO讀取數據

在前面咱們說過,任什麼時候候讀取數據,都不是直接從通道讀取,而是從通道讀取到緩衝區。因此使用NIO讀取數據能夠分爲下面三個步驟: 
1. 從FileInputStream獲取Channel 
2. 建立Buffer 
3. 將數據從Channel讀取到Buffer中

下面是一個簡單的使用NIO從文件中讀取數據的例子:

[java]   view plain  copy
 print ?
  1. import java.io.*;  
  2. import java.nio.*;  
  3. import java.nio.channels.*;  
  4.   
  5. public class Program {  
  6.     static public void main( String args[] ) throws Exception {  
  7.         FileInputStream fin = new FileInputStream("c:\\test.txt");  
  8.           
  9.         // 獲取通道  
  10.         FileChannel fc = fin.getChannel();  
  11.           
  12.         // 建立緩衝區  
  13.         ByteBuffer buffer = ByteBuffer.allocate(1024);  
  14.           
  15.         // 讀取數據到緩衝區  
  16.         fc.read(buffer);  
  17.           
  18.         buffer.flip();  
  19.           
  20.         while (buffer.remaining()>0) {  
  21.             byte b = buffer.get();  
  22.             System.out.print(((char)b));  
  23.         }  
  24.           
  25.         fin.close();  
  26.     }  
  27. }  

使用NIO寫入數據

使用NIO寫入數據與讀取數據的過程相似,一樣數據不是直接寫入通道,而是寫入緩衝區,能夠分爲下面三個步驟: 
1. 從FileInputStream獲取Channel 
2. 建立Buffer 
3. 將數據從Channel寫入到Buffer中

下面是一個簡單的使用NIO向文件中寫入數據的例子:

[java]   view plain  copy
 print ?
  1. import java.io.*;  
  2. import java.nio.*;  
  3. import java.nio.channels.*;  
  4.   
  5. public class Program {  
  6.     static private final byte message[] = { 8311110910132,  
  7.         9812111610111546 };  
  8.   
  9.     static public void main( String args[] ) throws Exception {  
  10.         FileOutputStream fout = new FileOutputStream( "c:\\test.txt" );  
  11.           
  12.         FileChannel fc = fout.getChannel();  
  13.           
  14.         ByteBuffer buffer = ByteBuffer.allocate( 1024 );  
  15.           
  16.         for (int i=0; i<message.length; ++i) {  
  17.             buffer.put( message[i] );  
  18.         }  
  19.           
  20.         buffer.flip();  
  21.           
  22.         fc.write( buffer );  
  23.           
  24.         fout.close();  
  25.     }  
  26. }  

本文介紹了Java NIO中三個核心概念中的兩個,而且看了兩個簡單的示例,分別是使用NIO進行數據的讀取和寫入,Java NIO中最重要的一塊Nonblocking I/O將在第三篇中進行分析,下篇將會介紹Buffer內部實現。

(未完待續)

詳細請看 http://blog.csdn.net/wuxianglong/article/details/6604817



相關文章
相關標籤/搜索