<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] # 通道(Channel) 通道表示打開到 IO 設備(例如:文件、套接字)的連接。 若需要使用 NIO 系統,需要獲取用于連接 IO 設備的通道以及用于容納數據的緩沖區。 然后操作緩沖區,對數據進行處理。Channel 負責傳輸, Buffer 負責存儲。 通道是由 java.nio.channels 包定義的。 Channel 表示 IO 源與目標打開的連接。 Channel 類似于傳統的“流”。只不過 Channel本身不能直接訪問數據, Channel 只能與Buffer 進行交互。 **通道都是操作緩存區完成全部的功能的** ## Java中所有已知 Channel 實現類: * AbstractInterruptibleChannel * AbstractSelectableChannel * DatagramChannel * FileChannel * Pipe.SinkChannel * Pipe.SourceChannel * SelectableChannel * ServerSocketChannel * SocketChannel 常用的有入下幾個: * FileChannel:用于讀取、寫入、映射和操作文件的通道,處理本地文件 * DatagramChannel:通過 UDP 讀寫網絡中的數據通道。 * SocketChannel:通過 TCP 讀寫網絡中的數據。 * ServerSocketChannel:可以監聽新進來的 TCP 連接,對每一個新進來的連接都會創建一個 SocketChannel。 ## 獲取通道 雖然FileChannel即可以讀取,也可以寫入.但是FileInputStream獲取的FileChannel只能讀,FileOutputStream獲取的FileChannel只能寫. RandomAccessFile獲取的FileChannel是只讀的還是讀寫的Channel,取決于RandomAccessFile打開文件的模式 **方式一** 對支持通道的對象調用getChannel() 方法。支持通道的類如下: * FileInputStream * FileOutputStream * RandomAccessFile * DatagramSocket * Socket * ServerSocket **方式二** 獲取通道的其他方式是使用 Files 類的靜態方法 newByteChannel() 獲取字節通道。 **方式三** 通過通道的靜態方法 open() 打開并返回指定通道。 ## 常用方法 * 分散(scatter)地從 Channel 中讀取是將數據讀入多個 Buffer 的操作。 因此,通道將來自通道的數據“分散”到多個緩沖區中。 * 聚集(gather)地寫入 Channel 是將來自多個緩沖區的數據寫入單個通道的操作。 因此,通道將來自多個緩沖區的數據“收集”到同一個通道中。 ![](https://img.kancloud.cn/14/f4/14f4c3e25dde4ce6a1bf7a10d65780ae_968x517.png) ## FileChannel 為了更形象解釋說明的Channel,下面準備以FileChannel的一些簡單代碼進行說明就容易懂了。 準備以FileOutputStream類為準,這兩個類都是支持通道操作的。 ~~~ String info[] = {"aa","xx"} ; File file = new File("d:" + File.separator + "testfilechannel.txt") ; FileOutputStream output = null ; FileChannel fout = null; try { output = new FileOutputStream(file) ; fout = null; fout = output.getChannel() ; // 得到輸出的通道 ByteBuffer buf = ByteBuffer.allocate(1024) ; for(int i=0;i<info.length;i++){ buf.put(info[i].getBytes()) ; // 字符串變為字節數組放進緩沖區之中 } buf.flip() ; fout.write(buf) ; // 輸出緩沖區的內容 } catch (Exception e) { e.printStackTrace(); }finally{ if(fout!=null){ try { fout.close() ; } catch (IOException e) { e.printStackTrace(); } } if(output!=null){ try { output.close() ; } catch (IOException e) { e.printStackTrace(); } } } ~~~ # DMA和channel 在DMA模式下,cpu只需要向DMA控制器下達指令,讓DMA控制器來處理數據的傳送,數據傳送完畢再把信息反饋給cpu,這樣很大程度能降低cpu的資源占用率,可以大大節省系統資源. DMA模式又分為Single-Word(單字節)和Multi-Word(多字節)兩種,其中能達到最大傳輸效率也只有16.6MB/S DMA大量發送消息,會有DMA總線沖突 ![](https://img.kancloud.cn/58/e1/58e152258c691b1aee720e3870cb6267_856x422.png) channel替代DMA ![](https://img.kancloud.cn/a9/68/a968a421d7458a81102daf4a640e20be_974x502.png) # 直接緩沖區和非直接緩沖區實現文件復制 ## 直接緩沖區 ~~~ @Test public void test2(){ FileChannel inChannel = null; FileChannel outChannel = null; try { long start = System.currentTimeMillis(); // String srcPath = "Dilraba.jpg"; // String destPath = "Dilraba3.jpg"; String srcPath = "C:\\Users\\Administrator\\Desktop\\score\\戰狼.mp4"; String destPath = "C:\\Users\\Administrator\\Desktop\\score\\戰狼1.mp4"; //實例化Channel inChannel = FileChannel.open(Paths.get(srcPath), StandardOpenOption.READ); outChannel = FileChannel.open(Paths.get(destPath), StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE); //得到直接緩沖區 MappedByteBuffer inMappedBuffer = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());//size():返回操作的文件的大小 MappedByteBuffer outMappedBuffer = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size()); //數據的讀寫操作 byte[] buffer = new byte[inMappedBuffer.limit()]; inMappedBuffer.get(buffer); outMappedBuffer.put(buffer); long end = System.currentTimeMillis(); System.out.println("直接緩沖區花費的時間:" + (end - start));//1929-1894 } catch (IOException e) { e.printStackTrace(); }finally{ if(inChannel != null){ try { inChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if(outChannel != null){ try { outChannel.close(); } catch (IOException e) { e.printStackTrace(); } } } } ~~~ ## 非直接緩沖區 ~~~ @Test public void test1(){ FileChannel inChannel = null; FileChannel outChannel = null; FileInputStream fis = null; FileOutputStream fos = null; try { long start = System.currentTimeMillis(); // String srcPath = "Dilraba.jpg"; // String destPath = "Dilraba2.jpg"; String srcPath = "C:\\Users\\Administrator\\Desktop\\score\\戰狼.mp4"; String destPath = "C:\\Users\\Administrator\\Desktop\\score\\戰狼2.mp4"; fis = new FileInputStream(srcPath); fos = new FileOutputStream(destPath); //實例化Channel inChannel = fis.getChannel(); outChannel = fos.getChannel(); //提供ByteBuffer ByteBuffer buffer = ByteBuffer.allocate(1024); while(inChannel.read(buffer) != -1){ buffer.flip();//修改為讀數據模式 outChannel.write(buffer); buffer.clear();//清空 } long end = System.currentTimeMillis(); System.out.println("非直接緩沖區花費的時間:" + (end - start));//20795-13768 } catch (Exception e) { e.printStackTrace(); }finally{ if(outChannel != null){ //關閉資源 try { outChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if(inChannel != null){ try { inChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if(fos != null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if(fis != null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } ~~~ # transferTo和transferFrom 將數據從源通道傳輸到其他Channel中 ~~~ FileChannel inChannel = FileChannel.open(Paths.get("Dilraba.jpg"), StandardOpenOption.READ); FileChannel outChannel = FileChannel.open(Paths.get("mm1.jpg"), StandardOpenOption.WRITE,StandardOpenOption.CREATE); //transferTo():將數據從可讀的Channel中轉換到可寫的Channel中 // inChannel.transferTo(0, inChannel.size(), outChannel); //transferFrom():將數據從可讀的Channel中轉換到可寫的Channel中 outChannel.transferFrom(inChannel, 0, inChannel.size()); inChannel.close(); outChannel.close(); ~~~ # 分散(Scatter)讀取和聚集(Gather)寫入 * 分散讀取(Scattering Reads)是指從Channel中讀取的數據分散到多個Buffer中 ![](https://img.kancloud.cn/ee/25/ee254d0bdef8e2e7067ac8df7721a6b5_600x371.png) 注意: 按照緩沖區的順序,從channel中讀取的數據依次將Buffer填滿 * 聚集寫入(Gathering Writes)是指將多個Buffer中的數據聚集到Channel ![](https://img.kancloud.cn/90/1a/901ab005e3b4094533f66999d1465c09_630x351.png) 注意: 按照緩沖區的順序,寫入position和limit之間的數據到Channel ~~~ RandomAccessFile readRaf = new RandomAccessFile("EclipseKeys.java", "r"); RandomAccessFile writeRaf = new RandomAccessFile("EclipseKeys1.java", "rw"); //實例化Channel FileChannel inChannel = readRaf.getChannel(); FileChannel outChannel = writeRaf.getChannel(); ByteBuffer buffer1 = ByteBuffer.allocate(1024); ByteBuffer buffer2 = ByteBuffer.allocate(2048); ByteBuffer[] dsts = {buffer1,buffer2}; inChannel.read(dsts);//分散讀取 //改為可讀模式 buffer1.flip(); buffer2.flip(); System.out.println(new String(buffer1.array(),0,buffer1.limit())); System.out.println(); System.out.println(new String(buffer2.array(),0,buffer2.limit())); //測試聚集寫入 outChannel.write(dsts); outChannel.close(); inChannel.close(); ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看