javaNIO和傳統BIO的區別:
- Java NIO和IO之間第一個最大的區別是,IO是面向流的,NIO是面向緩衝區的。 Java IO面向流意味着每次從流中讀一個或多個字節,直至讀取所有字節,它們沒有被緩存在任何地方。此外,它不能前後移動流中的數據。如果需要前後移動從流中讀取的數據,需要先將它緩存到一個緩衝區。 Java NIO的緩衝導向方法略有不同。數據讀取到一個它稍後處理的緩衝區,需要時可在緩衝區中前後移動。這就增加了處理過程中的靈活性。但是,還需要檢查是否該緩衝區中包含所有您需要處理的數據。而且,需確保當更多的數據讀入緩衝區時,不要覆蓋緩衝區裏尚未處理的數據。
- Java IO的各種流是阻塞的。這意味着,當一個線程調用read() 或 write()時,該線程被阻塞,直到有一些數據被讀取,或數據完全寫入。該線程在此期間不能再幹任何事情了。 Java NIO的非阻塞模式,使一個線程從某通道發送請求讀取數據,但是它僅能得到目前可用的數據,如果目前沒有數據可用時,就什麼都不會獲取。而不是保持線程阻塞,所以直至數據變的可以讀取之前,該線程可以繼續做其他的事情。 非阻塞寫也是如此。一個線程請求寫入一些數據到某通道,但不需要等待它完全寫入,這個線程同時可以去做別的事情。 線程通常將非阻塞IO的空閒時間用於在其它通道上執行IO操作,所以一個單獨的線程現在可以管理多個輸入和輸出通道(channel)。
NIO的幾個相關的概念:
Buffer(緩衝區) Channel(管道) Selector(多路複用器)
Buffer的基本操作:
public class TestBuffer {
public static void main(String[] args) {
// 1 基本操作
//創建指定長度的緩衝區
IntBuffer buf = IntBuffer.allocate(10);
buf.put(13);// position位置:0 - > 1
buf.put(21);// position位置:1 - > 2
buf.put(35);// position位置:2 - > 3
//把位置復位爲0,也就是position位置:3 - > 0
buf.flip();
System.out.println("使用flip復位:" + buf);
System.out.println("容量爲: " + buf.capacity()); //容量一旦初始化後不允許改變(warp方法包裹數組除外)
System.out.println("限制爲: " + buf.limit()); //由於只裝載了三個元素,所以可讀取或者操作的元素爲3 則limit=3
System.out.println("獲取下標爲1的元素:" + buf.get(1));
System.out.println("get(index)方法,position位置不改變:" + buf);
buf.put(1, 4);
System.out.println("put(index, change)方法,position位置不變:" + buf);;
for (int i = 0; i < buf.limit(); i++) {
//調用get方法會使其緩衝區位置(position)向後遞增一位
System.out.print(buf.get() + "\t");
}
System.out.println("buf對象遍歷之後爲: " + buf);
// 2 wrap方法使用
/**
// wrap方法會包裹一個數組: 一般這種用法不會先初始化緩存對象的長度,因爲沒有意義,最後還會被wrap所包裹的數組覆蓋掉。
// 並且wrap方法修改緩衝區對象的時候,數組本身也會跟着發生變化。
int[] arr = new int[]{1,2,5};
IntBuffer buf1 = IntBuffer.wrap(arr);
System.out.println(buf1);
IntBuffer buf2 = IntBuffer.wrap(arr, 0 , 2);
//這樣使用表示容量爲數組arr的長度,但是可操作的元素只有實際進入緩存區的元素長度
System.out.println(buf2);
*/
// 3 其他方法
/**
IntBuffer buf1 = IntBuffer.allocate(10);
int[] arr = new int[]{1,2,5};
buf1.put(arr);
System.out.println(buf1);
//一種複製方法
IntBuffer buf3 = buf1.duplicate();
System.out.println(buf3);
//設置buf1的位置屬性
//buf1.position(0);
buf1.flip();
System.out.println(buf1);
System.out.println("可讀數據爲:" + buf1.remaining());
int[] arr2 = new int[buf1.remaining()];
//將緩衝區數據放入arr2數組中去
buf1.get(arr2);
for(int i : arr2){
System.out.print(Integer.toString(i) + ",");
}
*/
}
}