使用NIO提升性能
在軟件系統中,由於I/O的速度要比內存慢,因此I/O讀寫在很多場合都會成爲系統瓶頸,提升I/O速度對提升系統性能有着很大的好處。
在java的標準I/O中,提供了基於流的I/O實現,即InputStream和OutputStream。這種基於流的實現,以字節爲單位處理數據,並且非常容易建立各種過濾器。
NIO就是New的I/O簡稱,它表示新一套的標準,具有以下特性:
- 爲所有的原始類型提供(Buffer)緩存支持
- 使用Java.nio.charset.Charset作爲字符編碼解碼解決方案。
- 增加(Channel)對象,作爲新的原始I/O抽象。
- 支持鎖和內存映射文件的文件訪問接口
- 提供了基於Selector的異步網絡I/O
與流式I/O不同,NIO是基於塊(Block)的,它以塊的基本單位處理數據。在NIO中,最爲重要的兩個組件是緩衝Buffer和通道Channel。緩衝是一塊連續的內存塊,是NIO讀寫數據的中轉池,通道表示緩衝數據的源頭或者目的地,它用於向緩衝讀取或寫入數據,是訪問緩衝的接口。
在NIO的實現中,Buffer是一個抽象類,JDK爲每一個原生類型都創建了一個Buffer
除了ByteBuffer外,其他每一種Buffer都具備完全一樣的操作,唯一的區別僅在於他們所對應的數據類型。因爲ByteBuffer多用於絕大多數標準IO操作接口,因此它有一些特殊的方法,有點類似Stream,但Stream是單向的。應用程序中不能直接對Channel進行讀寫操作,而必須通過Buffer來進行,比如在讀一個Channel的時候,需要先將數據讀入到相對應的Buffer,然後再Buffer中進行讀取。
以一個簡單的文件爲例,在讀取文件時,首先將文件打開,並取得文件的Channel:
public class Demo {
public static void main(String[] args) throws Exception {
String path="D:"+File.separator+"charTest.txt";
FileInputStream fis=new FileInputStream(new File(path));
FileChannel fc=fis.getChannel();
//要從文件Channel中讀取數據,必須使用Buffer
ByteBuffer bf=ByteBuffer.allocate(1024);
while(fc.read(bf)>0) {
//把ByteBuffer從寫模式,轉變成讀取模式,即使把position的位置變成0,
//limit的位置變成position。因爲這時候
//已經把數據讀到緩衝區了,所以要復位一下,才能讀。(重置到開始的位置,開始讀)
bf.flip();
//下面這兩個是把緩衝區的數據打印下來
Charset charset=Charset.forName("UTF-8");
System.out.println(charset.newDecoder().decode(bf).toString());
}
fc.close();
fis.close();
}
}
結果:
新中國成立了!!!
加油。
Buffer的基本原理
Buffer中有三個重要的參數:位置(position)、容量(capactiy)和上限(limit)
文件複製操作: