Java NIO小結 (一)

    自JDK1.4後,Java推出了New/IO(java.nio.*)。在JDK1.4之前,原IO(java.io.*)處理只能是stream的方式 逐個字節逐個字節讀取或者寫入。流處理方式性能低。而New/IO處理數據時以塊爲單位,系統的IO開銷小,但IO性能高。



New/IO的4個核心概念

Buffer 處理IO時,數據的載體

Charset 把unicode字符進行編碼成字節碼或者把字節碼反編成unicode字符

Channel 連接着能進行IO操作的實體,比如一個Channel可以連接一個輸入流,也可以連接一個輸出流,還可以連接一個輸入流和一個輸入流,根據channel上連接的具體的流,可以進行輸入或輸出操作。

SelectorSelectionKey 與Selectable Channel一起,定義了多路複用和Non-Blocking IO操作能力。


Blocking IO和Non-Blocking IO

阻塞IO模式下,任何IO操作會阻塞Channel直到這個IO操作完成後,方可在這個通道上進行其它IO操作。非阻塞模式下,一個IO操作調用時,通道不會被阻塞,即使這個IO操作只傳輸了少量數據甚至完全沒有傳輸數據。非阻塞模式最適用於多路複用IO編程,比如服務器端socket編程。

 

在JDK1.4中,傳統的IO與New/IO已經有很好的集成,在傳統的io包中,可以使用Channel,但是要根據具體的輸入和輸出流來決定。比如下 面的代碼先定義一個文件輸入流,通過文件輸入流的FileChannel讀取文件的頭512個字節到緩存中,然後使用utf-8編碼器把緩存中的內容反編 碼成一個utf-8字符串。

 

Charset utf8 = Charset.forName("utf-8");
ByteBuffer buffer = ByteBuffer.allocate(512);
FileInputStream fis = new FileInputStream("a.txt");
FileChannel fileChannel = fis.getChannel();
fileChannel.read(buffer);
buffer.flip();
String content = utf8.decode(buffer);

 

反之,用FileChannel寫入文件也是相當的方便,和讀取類似。FileChannel寫入的方式依賴於輸入流的打開方式。下面的代碼以 Append方式打開一個文件輸出流,用這個流的FileChannel寫入編碼後的“hello java new IO"字符串。

 

FileOutputStream fos = new FileOutputStream("a.txt", true);
FileChannel fileChannel = fos.getChannel();		 
fileChannel.write(utf8.encode("hello java new IO"));

 

使用Channel的優點在於channel是可以同時輸入輸出的,而不要像傳統的io那樣打開一個輸入流,打開一個輸出流,在讀/寫時,這兩個流總是要配對使用,下面的代碼展示如何用一個FileChannel做輸入和輸出兩種IO操作。

Charset utf8 = Charset.forName("utf-8");
//以讀寫方式隨機存儲文件
RandomAccessFile raf = new RandomAccessFile("1.txt", "rws");
FileChannel fc = raf.getChannel();

//寫入hello file channel到文件中
fc.write(utf8.encode("hello file channel"));

//分配10個字節緩存
ByteBuffer buff = ByteBuffer.allocate(10);

//從文件起始位置開始讀取10個字節,並輸出
fc.read(buff, 0);
buff.flip();
System.out.println(utf8.decode(buff)); // 輸出hello file
fc.close();
raf.close();

 

 

 

[原創內容,版權所有,如有轉載,請註明出處,如有錯誤之處,請指出,不勝感激]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章