javaNIO實戰4----> java NIO的通道Channel實戰
1、IO發展三部曲
在計算機的發展歷史中,IO的發展一共經歷了三個時期,分別如下:
第一階段:CPU直接負責IO請求的處理,將檔案資料從磁碟讀取到記憶體中,然後再響應應用的IO請求,嚴重影響CPU的效能模型圖如下:
第二階段:DMA(Direct Memory Access)直接儲存器 負責IO請求,不過DMA也會向CPU去獲取授權資訊,如果在頻繁進行IO操作的話,也會嚴重影響CPU的效能。模型圖如下:
第三階段:使用Channel來替換DMA完成CPU對於IO請求的解放階段,Channel完全接管了IO請求,不需要CPU的參與,讓CPU全心全意做其他事情。模型如下:
2、NIO中Channel的概念以及作用
在介紹NIO的時候我們談及到Channel(通道)的概念,其實他就是特殊的IO流,只不過它比傳統的IO流擁有更多的功能。在NIO中Channel主要就是用來連線輸入檔案與讀取點、連線輸出檔案與寫出點、緩衝區中資料的填充與清理、傳輸緩衝區中的資料。注意Channel本身不儲存資料,因此需要配合緩衝區進行傳輸,注意讀取點、寫入點一般情況下是我們的應用程式。
3、NIO中Channel的主要實現類
FileChannel:主要用於本地檔案傳輸。
SocketChannel、ServerSocketChannel:主要用於TCP網路IO傳輸。
DatagramChannel:主要用於UDP網路IO傳輸。
4、如何建立通道Channel ?
方式1:可以使用本地IO流例項通過getChannel()來獲取通道,如下IO流支援獲取Channel
FileInputStream、FileOutputStream、RandomAccessFile 案例如下:
@Test
public void test3() throws FileNotFoundException {
FileInputStream fis = new FileInputStream("C://test.txt");
FileChannel channel = fis.getChannel();
FileOutputStream fos = new FileOutputStream("d://testCopy.txt");
FileChannel channel1 = fos.getChannel();
RandomAccessFile randomAccessFile = new RandomAccessFile("E://aaa.txt","E://aaa.txt");
FileChannel channel2 = randomAccessFile.getChannel();
}
上面的案例是針對本地IO流來獲取FileChannel的,網路IO也可以獲取到通道,案例如下:
@Test
public void test4() throws IOException {
Socket socket = new Socket();
SocketChannel channel1 = socket.getChannel();
ServerSocket serverSocket = new ServerSocket(8080);
ServerSocketChannel channe2 = serverSocket.getChannel();
}
方式2:在Java1.7 以後中NIO.2 針對各個通道的實現提供靜態方法open()。
在Java1.7以後更新的NIO的的部分統稱為NIO.2,案例如下:
@Test
public void test5() throws IOException {
FileChannel fileChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.READ);
}
網路中的IO通道也是可以使用open()方法直接獲取的。
方式3:可以使用Java1.7中NIO.2的Files工具類的newByteChannel()獲取:
@Test
public void test7() throws IOException {
SeekableByteChannel seekableByteChannel = Files.newByteChannel(Paths.get("2.jpg"), StandardOpenOption.READ);
}
5、案例--->使用Channel進行檔案copy:
實現1:使用檔案流獲取通道的方式:
@Test
public void test8() throws IOException {
FileInputStream fileInputStream = new FileInputStream("2.jpg");
FileOutputStream fileOutputStream = new FileOutputStream("3.jpg");
FileChannel inChannel = fileInputStream.getChannel();
FileChannel outChannel = fileOutputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
迴圈使用inChannel來讀取資料到緩衝區中,當沒有讀取到資料表示讀取結束
while(inChannel.read(buffer) != -1){
讀完一個次,先將緩衝區切換為寫模式,然後使用outChannel將本次讀取的資料寫入到3.jpg中
buffer.flip();
outChannel.write(buffer);
寫完後再清理緩衝區。清理緩衝區後不需要再次切換為讀模式了,因為clear會重置position=0、limit=capacity
buffer.clear();
}
}
實現2:使用靜態open()方法獲取通道,然後複製檔案:
@Test
public void test9() throws IOException {
FileChannel inChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("4.jpg"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
//StandardOpenOption.CREATE:存在檔案就覆蓋,不存在就建立。
//StandardOpenOption.CREATE_NEW:存在檔案就報錯,不存在就建立。
ByteBuffer buffer = ByteBuffer.allocate(1024);
迴圈使用inChannel來讀取資料到緩衝區中,當沒有讀取到資料表示讀取結束
while(inChannel.read(buffer) != -1){
讀完一個次,先將緩衝區切換為寫模式,然後使用outChannel將本次讀取的資料寫入到3.jpg中
buffer.flip();
outChannel.write(buffer);
寫完後再清理緩衝區。清理緩衝區後不需要再次切換為讀模式了,因為clear會重置position=0、limit=capacity
buffer.clear();
}
}
相關文章
- Java NIO 之 Channel(通道)Java
- Java-NIO之Channel(通道)Java
- Java技術分享:NIO實戰教程!Java
- 最新Java培訓-NIO實戰教程Java
- nio再學習之通道channel
- k8s 實戰 4----副本集K8S
- Java NIO:通道Java
- Java NIO Channel 使用Java
- 清華尹成帶你實戰GO案例(21)Go 並行通道ChannelGo並行
- Java NIO - Channel 與 SelectorJava
- Java NIO:Buffer、Channel 和 SelectorJava
- Java NIO系列教程(二) ChannelJava
- channel 實戰應用,這篇就夠了!
- Go實戰-基於Go協程和channel的使用Go
- Java NIO學習系列二:ChannelJava
- Java集合實戰Java
- Java NIO 檔案通道 FileChannel 用法Java
- 【Java】NIO中Channel的註冊原始碼分析Java原始碼
- 【譯】Java NIO 簡明教程系列之 ChannelJava
- 【Java 8實戰】Extension MethodsJava
- java core dump分析實戰Java
- java nio中的select和channel是怎麼使用的?Java
- Java 實現的SnowFlake生成UUID (Java程式碼實戰-007)JavaUI
- Java ThreadLocal (Java程式碼實戰-006)Javathread
- Java ConcurrentHashMap (Java程式碼實戰-005)JavaHashMap
- Java ReEntrantLock (Java程式碼實戰-001)JavaReentrantLock
- Java AtomicBoolean (Java程式碼實戰-008)JavaBoolean
- Java 8 Stream之實戰篇Java
- Java 反射理解以及Android實戰Java反射Android
- java8實戰學習Java
- NIO(六)selector和channel的使用
- Java volatile 的測試(Java程式碼實戰-004)Java
- NIO(四)channel總結
- Flutter外掛開發指南01: 通道Channel的編寫與實現Flutter
- 清華尹成帶你實戰GO案例(56)Go通道的同步功能Go
- Java高併發實戰,鎖的優化Java優化
- 清華尹成帶你實戰GO案例(57)Go通道方向Go
- Golang通道Channel詳解Golang