日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

3.通道 Channel

發(fā)布時(shí)間:2024/4/17 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 3.通道 Channel 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、通道(Channel):由java.nio.channels包定義的 。Channel 表示 IO 源與目標(biāo)打開(kāi)的連接。

Channel 類(lèi)似于傳統(tǒng)的 ‘流’。只不過(guò) Channel 本身不能直接訪問(wèn)數(shù)據(jù),Channel只能與Buffer進(jìn)行交互

?

二、 /*通道的主要實(shí)現(xiàn)類(lèi)*/

Java 為 Channel 接口提供的 最主要實(shí)現(xiàn)類(lèi)如下:

  FileChannel:用于讀取、寫(xiě)入、映射和操作文件的通道

  SocketChannel:通過(guò)TCP 讀寫(xiě)網(wǎng)絡(luò)中的數(shù)據(jù)

  ServerSocketChannel:可以監(jiān)聽(tīng)新進(jìn)來(lái)的TCP連接,對(duì)每一個(gè)新進(jìn)來(lái)的連接都會(huì)創(chuàng)建一個(gè) SocketChannel

?

三、 /*如何獲取通道*/

獲取通道

  * 1.Java針對(duì) 支持通道的類(lèi)提供了 getChannel()方法

    * 本地IO:

      * FileInputStream/FileOutputStream

      * RandomAccessFile


    * 網(wǎng)絡(luò)IO:

      * Socket

      * ServerSocket

      * DatagramSocket


  2.在 JDK1.7 中 的 NIO.2 針對(duì)各個(gè)通道提供了靜態(tài)方法 open()

  3.在 JDK1.7 中 的 NIO.2 的 File 工具類(lèi)的newByteChannel()

?

利用通道進(jìn)行數(shù)據(jù)傳輸

?


四、 /*通道之間的數(shù)據(jù)傳輸*/

  transferForm() 將數(shù)據(jù)從源通道 傳輸?shù)狡渌?Channel中

  transferTo() 其他 Channel 從 原通道中 獲取數(shù)據(jù)

  

五、 /*分散(Scatter) 與 聚集(Gather)*/

  分散讀取(Scattering Reads):將通道中的數(shù)據(jù)分散到多個(gè)緩沖區(qū)

  聚集寫(xiě)入(Gathering Writes):將多個(gè)緩沖區(qū)中的 數(shù)據(jù) 聚集到通道中

  
六、 /*字符集:Charset*/

  編碼:字符串 -> 字節(jié)數(shù)組

  解碼: 字節(jié)數(shù)組 -> 字符串
  

?

1 /* 2 * 一、通道(Channel):用于源節(jié)點(diǎn) 與目標(biāo)節(jié)點(diǎn)的連接 ,在java nio 中 負(fù)責(zé)緩沖區(qū)中數(shù)據(jù)的傳輸。Channel 本身不存儲(chǔ)數(shù)據(jù),因此需要配合緩沖區(qū)進(jìn)行傳輸 3 * 4 * 二、通道的主要實(shí)現(xiàn)類(lèi) 5 * java.nio.channels.Channel 接口 6 * |--FileChannel 7 * |--SocketChannel 8 * |--ServerSocketChannel 9 * |--DatagramChannel 10 * 11 * 三、獲取通道 12 * 1.Java針對(duì) 支持通道的類(lèi)提供了 getChannel()方法 13 * 本地IO: 14 * FileInputStream/FileOutputStream 15 * RandomAccessFile 16 * 17 * 網(wǎng)絡(luò)IO: 18 * Socket 19 * ServerSocket 20 * DatagramSocket 21 * 22 * 2.在 JDK1.7 中 的 NIO.2 針對(duì)各個(gè)通道提供了靜態(tài)方法 open() 23 * 24 * 3.在 JDK1.7 中 的 NIO.2 的 File 工具類(lèi)的newByteChannel() 25 * 26 * 四、通道之間的數(shù)據(jù)傳輸 27 * transferForm() 28 * transferTo() 29 * 30 * 五、分散(Scatter) 與 聚集(Gather) 31 * 分散讀取(Scattering Reads):將通道中的數(shù)據(jù)分散到多個(gè)緩沖區(qū) 32 * 聚集寫(xiě)入(Gathering Writes):將多個(gè)緩沖區(qū)中的 數(shù)據(jù) 聚集到通道中 33 * 34 * 六、字符集:Charset 35 * 編碼:字符串 -> 字節(jié)數(shù)組 36 * 解碼: 字節(jié)數(shù)組 -> 字符串 37 * 38 * */ 39 public class TestChannel { 40 41 //使用指定字符集 進(jìn)行編碼 和 解碼 42 @Test 43 public void test6() throws IOException { 44 //1.選擇字符集 45 Charset charset1 = Charset.forName("GBK"); 46 47 //2.獲取編碼器 48 CharsetEncoder encoder = charset1.newEncoder(); 49 50 //3.獲取解碼器 51 CharsetDecoder decoder = charset1.newDecoder(); 52 53 //4.創(chuàng)建字符串緩沖區(qū),放入需要編碼的字符串 54 CharBuffer charBuffer = CharBuffer.allocate(1024); 55 charBuffer.put("迅雷影音"); 56 57 //5.對(duì)字符串進(jìn)行編碼 (編碼:字符串 -> 字節(jié)數(shù)組) 58 charBuffer.flip(); //操作字符串緩沖區(qū),解碼字符串之前 需要 flip 一下 59 ByteBuffer byteBuffer = encoder.encode(charBuffer); 60 61 // byteBuffer 此時(shí) 是 初始狀態(tài),即position 是0 62 //調(diào)用 這個(gè) for ,每 get 一次,position + 1 63 //這樣才能 在 flip 之后, 解碼 需要操作的數(shù)據(jù) 64 for(int i = 0;i<8;i++) { 65 System.out.println(byteBuffer.position()); 66 System.out.println(byteBuffer.get()); 67 } 68 69 //6.對(duì)字節(jié)數(shù)組進(jìn)行解碼 (解碼: 字節(jié)數(shù)組 -> 字符串) 70 byteBuffer.flip(); //操作字節(jié)緩沖區(qū),解碼字節(jié)數(shù)組之前 需要 flip 一下 71 CharBuffer charBuffer2 = decoder.decode(byteBuffer); 72 73 //打印解碼后的數(shù)據(jù) 74 System.out.println(charBuffer2.toString()); 75 } 76 77 //5.顯示所有的字符集 78 @Test 79 public void test5() { 80 Map<String,Charset> map = Charset.availableCharsets(); 81 Set<Entry<String, Charset>> set = map.entrySet(); 82 83 for(Entry<String, Charset> entry:set) { 84 System.out.println(entry.getKey() + " = " + entry.getValue()); 85 } 86 } 87 88 //4.分散和 聚集 (多個(gè)緩沖區(qū)) 89 @Test 90 public void test4() throws IOException { 91 // "rw" 是指 具有read 和 write 的 權(quán)限 92 RandomAccessFile raf = new RandomAccessFile("1.txt", "rw"); 93 //1.獲取通道 94 FileChannel channel1 = raf.getChannel(); 95 96 //2.分配指定大小的緩沖區(qū) (多個(gè)) 97 ByteBuffer buf1 = ByteBuffer.allocate(100); 98 ByteBuffer buf2 = ByteBuffer.allocate(1024); 99 ByteBuffer[] bufs = {buf1,buf2}; 100 101 102 //4.聚集寫(xiě)入 103 RandomAccessFile raf2 = new RandomAccessFile("2.txt","rw"); 104 FileChannel channel2 = raf2.getChannel(); 105 106 107 //3.分散讀取 108 while(channel1.read(bufs)!= -1) { 109 for(ByteBuffer buf:bufs) { 110 buf.flip(); 111 } 112 //4.聚集寫(xiě)入 113 channel2.write(bufs); 114 115 System.out.println("-----------------緩沖區(qū)1---------------"); 116 System.out.println(new String(bufs[0].array(),0,bufs[0].limit()) ); 117 System.out.println("-----------------緩沖區(qū)1---------------"); 118 119 System.out.println("-----------------緩沖區(qū)2---------------"); 120 System.out.println(new String(bufs[1].array(),0,bufs[1].limit())); 121 System.out.println("-----------------緩沖區(qū)2---------------"); 122 123 for(ByteBuffer buf:bufs) { 124 buf.clear(); 125 } 126 127 128 } 129 130 } 131 132 //3.通道之間的數(shù)據(jù)傳輸 133 @Test 134 public void test3() throws Exception { 135 FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ); 136 FileChannel outChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE); 137 138 //直接使用transferTo 或者 transferFrom 完成通道之間的數(shù)據(jù)傳輸 139 inChannel.transferTo(0, inChannel.size(), outChannel); 140 outChannel.transferFrom(inChannel, 0, inChannel.size()); 141 142 inChannel.close(); 143 outChannel.close(); 144 } 145 146 //2.使用直接緩沖區(qū)完成文件的復(fù)制(內(nèi)存映射文件)(這種方式效率更高) 147 //會(huì)出現(xiàn)的問(wèn)題 :文件傳輸已經(jīng)完成,但是程序仍然沒(méi)有結(jié)束,因?yàn)?java 虛擬機(jī)無(wú)法及時(shí) 對(duì) 內(nèi)存映射文件進(jìn)行 進(jìn)行釋放,必須要等指向映射文件的那個(gè)變量被回收 148 @Test 149 public void test2() { 150 151 long start = System.currentTimeMillis(); 152 153 FileChannel inChannel = null; 154 FileChannel outChannel = null; 155 MappedByteBuffer inMapperBuf = null; 156 MappedByteBuffer outMapperBuf = null; 157 158 try { 159 //使用 FileChannel 的 open方法 (可以不用創(chuàng)建流就可以得到通道) 160 inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ); 161 outChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE); 162 163 //內(nèi)存映射文件 (也是一個(gè) 緩沖區(qū) ,繼承自 ByteBuffer,直接緩沖區(qū)也只能使用 ByteBuffer) 164 inMapperBuf = inChannel.map(MapMode.READ_ONLY,0 , inChannel.size()); 165 outMapperBuf = outChannel.map(MapMode.READ_WRITE,0 , inChannel.size()); 166 167 } catch (IOException e) { 168 e.printStackTrace(); 169 } 170 171 172 //直接對(duì)緩沖區(qū)進(jìn)行數(shù)據(jù)讀寫(xiě)操作 173 byte[] bytes = new byte[inMapperBuf.limit()]; 174 inMapperBuf.get(bytes); 175 outMapperBuf.put(bytes); 176 177 try { 178 if(inChannel != null) { 179 inChannel.close(); 180 } 181 if(outChannel != null) { 182 outChannel.close(); 183 } 184 } catch (IOException e) { 185 e.printStackTrace(); 186 } 187 188 long end = System.currentTimeMillis(); 189 System.out.println("花費(fèi):" + (end-start)); 190 191 } 192 193 //1.利用通道完成文件的復(fù)制 194 @Test 195 public void test1() { 196 long start = System.currentTimeMillis(); 197 198 FileInputStream fis = null; 199 FileOutputStream fos = null; 200 try { 201 fis = new FileInputStream("1.jpg"); 202 fos = new FileOutputStream("2.jpg"); 203 } catch (FileNotFoundException e) { 204 e.printStackTrace(); 205 } 206 207 //1.獲取流對(duì)應(yīng)的 通道 208 FileChannel inChannel = fis.getChannel(); 209 FileChannel outChannel = fos.getChannel(); 210 211 //2.分配指定大小的緩沖區(qū) 212 ByteBuffer buffer = ByteBuffer.allocate(1024); 213 214 //3.將通道中的數(shù)據(jù)存入緩存區(qū) 215 try { 216 //read 方法,從Channel 中讀取數(shù)據(jù)到 ByteBuffer (即往 緩沖區(qū)中 put 數(shù)據(jù)),所以不用 flip 217 while(inChannel.read(buffer) != -1) { 218 buffer.flip(); //切換到讀取數(shù)據(jù)模式 219 220 //4.將緩存區(qū)中的數(shù)據(jù)寫(xiě)入通道中 (需要get 出 緩沖區(qū)中的 數(shù)據(jù) ,所以需要 flip) 221 outChannel.write(buffer); 222 buffer.clear(); //清空緩沖區(qū),使其繼續(xù)循環(huán) 223 } 224 } catch (IOException e) { 225 e.printStackTrace(); 226 } finally { 227 if(inChannel != null) { 228 try { 229 inChannel.close(); 230 } catch (IOException e) { 231 e.printStackTrace(); 232 } 233 } 234 if(outChannel != null) { 235 try { 236 outChannel.close(); 237 } catch (IOException e) { 238 e.printStackTrace(); 239 } 240 } 241 if(fis != null) { 242 try { 243 fis.close(); 244 } catch (IOException e) { 245 e.printStackTrace(); 246 } 247 } 248 if(fos != null) { 249 try { 250 fos.close(); 251 } catch (IOException e) { 252 e.printStackTrace(); 253 } 254 } 255 } 256 257 long end = System.currentTimeMillis(); 258 System.out.println("花費(fèi):" + (end-start)); 259 } 260 261 }

?


  

轉(zhuǎn)載于:https://www.cnblogs.com/xuzekun/p/7435504.html

總結(jié)

以上是生活随笔為你收集整理的3.通道 Channel的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。