Java NIO學習篇之NIO的基本認識

定義:

NIO:是從jdk1.4提出的,本意是New IO(相對於傳統的IO),也叫 No Blocked IO(只相對於網絡IO),它的出現彌補傳統IO的不足,提出了更加高效的方式。

NIO對於網絡IO而言:

jdk1.4:採用了基於select/poll的多路複用IO模型。
jdk1.5及以上:採用了基於epoll的多路複用IO模型。

IO模型可查看:詳解Unix5種IO模型

NIO對於文件IO而言:

NIO對基於文件的IO還是阻塞模型的IO。只有基於網絡IO纔是非阻塞的。

NIO的新特性:

  1. 基於通道(Channel)和緩衝區(Buffer)操作
  • 通道(Channel):一個新的、原始的IO抽象。
  • 緩衝區支持(Buffer):爲所有的原始類型提供緩衝區支持。也就是說NIO是強制基於通道和緩衝區操作的。
  • 具體操作:數據從通道讀到緩衝區,數據從緩衝區寫入通道(用戶進程角度)。
  1. 非阻塞(針對網絡IO)
  • 提供多路複用、非阻塞的IO操作,即當前線程從通道讀取數組到緩衝區時,或者把緩衝區數據寫入到通道時,線程依然可以進行其他事情。
  1. 選擇器(selectors)(針對網絡IO)
  • 用戶監聽多個通道的事件,如:連接打開,數據到達等,單個線程可監聽多個數據通道。
  1. 其他
  • 提供字符集編碼、解碼解決方案:java.nio.Charset。
  • 支持鎖和內存映射文件的文件訪問接口。

核心組件:

  • 通道(Channel):Java NIO的數據來源,可以是網絡,也可以是本地磁盤。表示打開到IO設備(文件、套接字)的連接。
  • 緩衝區(Buffer):數據讀寫的中轉區。用於容納數據。
  • 選擇器(Selectors):異步IO的核心類,可以實現異步非阻塞IO,一個Selectors可以管理多個通道Channel。

一個複製文件的小demo:

/**
 * @author YeHaocong
 * @decription 一個NIO的Demo,完成對文件的複製
 * @Date 2020/5/18 18:52
 */

public class NIOFirstDemo {

    public static void main(String[] args) {

        try (FileInputStream fis = new FileInputStream("test_nio1.txt");
             FileOutputStream fos  = new FileOutputStream("test_nio1_cp.txt")){

            //獲取通道,連接源節點和目標節點,通道本身不存儲任何數據,因此需要緩衝區配合傳輸。
            FileChannel fisChannel = fis.getChannel();
            //獲取通道,連接源節點和目標節點,通道本身不存儲任何數據,因此需要緩衝區配合傳輸。
            FileChannel fosChannel = fos.getChannel();

            //創建緩衝區,並分配1024字節。

            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

            //把文件的數據通過通道傳輸寫到ByteBuffer緩衝區中
            fisChannel.read(byteBuffer);

            //把緩衝區該爲讀模式。
            byteBuffer.flip();

            //讀取byteBuffer裏面的數據通過輸出流通道寫到文件中
            fosChannel.write(byteBuffer);

            //清空緩衝區
            byteBuffer.clear();
			//關閉通道與流
            fisChannel.close();
            fosChannel.close();
            fis.close();
            fos.close();
        }catch (IOException e){

        }
    }
}

IO和NIO的區別:

類型 面向操作域 處理數據 IO阻塞/非阻塞(基於網絡IO)
Java IO 可以面向緩衝區,也可以直接面向數據源,使用流進行傳輸 沒有緩衝區的話是直接讀取字節或者字符,並且無法前後移動數據流中的數據 阻塞:當一個線程在讀/寫時,當數據完全被讀取/寫入或者數據沒有準備好時,線程不能做其他任務,只能一直阻塞等待,知道數據準備好後才能繼續。
Java NIO 強制通道和緩衝區 先讀取數據到緩衝區,並且可以前後移動數據量中的數據 非阻塞:當一個線程在讀/寫時,當數據完全被讀取/寫入或者數據沒有準備好時,線程可以做其他任務(控制其他通道),知道數據準備好後再切換回該通道。繼續讀取、寫入。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章