java NIO
概念
在講到這個概念之前,我們先回想一下:我們在使用 Scanner 操作的時候,是不是進程需要等待着你從控制檯輸入之後,下面的代碼才能夠繼續執行。換句話,如果你遲遲不輸入,代碼是不會向下進行的,這種現象我們稱之爲阻塞IO。除了Scanner操作之外,文件的讀寫,Socket數據傳輸都是阻塞IO(下面用BIO代替,Basic IO 或者 Block IO)。
那麼與 BIO 相反的就是 NIO(New IO 新IO,Non-Block IO 非阻塞IO)。NIO 運行當前程序在處理IO事物時,不會影響其他程序的運行,可以在不適用多線程的情況下,滿足IO操作要求。
三大核心
-
通道
Channel 文件操作,網絡數據傳遞操作使用的通道。 -
緩衝
Buffer 緩衝使用可以提高操作效率,減少不必要的讀寫次數 -
選擇器
Selector 監聽多個channel狀態,用來管理Channel
Channel 和 Buffer 完成文件操作
- Buffer 中常用方法
方法名 | 作用 |
---|---|
allocate(int capacity) | 靜態方法,按照指定的字節數分配緩衝區空間,返回值爲字節緩衝 |
get() | 從字節緩衝對象中讀取一個 byte 類型的數據 |
flip() | 翻轉緩衝區,回到緩衝區的開始位置。 |
wrap(byte[] arr); | 存入一個byte類型數組到緩衝區,會得到一個新的ByteBuffer |
put(byte[] b); | 將字節數組存入緩衝去 |
- Channer 接口
方法名 | 作用 |
---|---|
read(ByteBuffer buffer) | 從通道中讀取數據到ByteBuffer中 |
write(ByteBuffer buffer) | 從Buffer中寫數據到通道中 |
transferFrom(ReadableByteChannel src, long position, long count) | 從指定srcChannel中,指定位置position開始,讀取count個元素,到當前通道中 |
文件複製操作。 | |
transferTo(long position, long count, WritableByteChannel target) | 將當前通道中的數據寫入到target中,從當前通道的position位置開始,計數count |
實例1——通過NIO寫入數據到文件中的操作
- 文件操作字節輸出流
FileOutputStream fos = new FileOutputStream("F:/創建文件/1.txt");
- 利用文件操作輸出流對象獲取對應的Channel通道
FileChannel foc = fos.getChannel();
- 準備一個緩衝區 4KB緩衝區
ByteBuffer buffer = ByteBuffer.allocate(1024 * 4);
- 準備數據放入緩衝區中
String str = "測試NIO";
buffer.put(str.getBytes());
- 讓緩衝區中的指針回到最初的位置(緩衝區中的指針在存入數據的時候已經移動到存入數據的末尾,如果此時將衝區的數據寫入到通道中,寫入的內容是指針之後的內容)【注意】
buffer.flip();
- 緩衝區數據寫入到通道中
foc.write(buffer);
- 關閉資源
fos.close();
實例2——拷貝文件
- 安排輸出流和輸入流
FileInputStream fis = new FileInputStream("F:/創建文件/1.mp4");
FileOutputStream fos = new FileOutputStream("F:/創建文件/2.mp4");
- 準備兩個Channel對象
FileChannel srcChannel = fis.getChannel();
FileChannel dstChannel = fos.getChannel();
- 進行拷貝
srcChannel.transferTo(0, srcChannel.size(), dstChannel);
//dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
- 關閉資源
fos.close();
fis.close();