Java NIO網路程式設計
阿新 • • 發佈:2019-02-09
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) + ",");
}
*/
}
}