Java NIO網絡編程

javaNIO和傳統BIO的區別:

  1. Java NIO和IO之間第一個最大的區別是,IO是面向流的,NIO是面向緩衝區的。 Java IO面向流意味着每次從流中讀一個或多個字節,直至讀取所有字節,它們沒有被緩存在任何地方。此外,它不能前後移動流中的數據。如果需要前後移動從流中讀取的數據,需要先將它緩存到一個緩衝區。 Java NIO的緩衝導向方法略有不同。數據讀取到一個它稍後處理的緩衝區,需要時可在緩衝區中前後移動。這就增加了處理過程中的靈活性。但是,還需要檢查是否該緩衝區中包含所有您需要處理的數據。而且,需確保當更多的數據讀入緩衝區時,不要覆蓋緩衝區裏尚未處理的數據。
  2. 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) + ",");
        }
        */

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