博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NIO之Channel聚集(gather)写入与分散(scatter)读取
阅读量:6219 次
发布时间:2019-06-21

本文共 7474 字,大约阅读时间需要 24 分钟。

Channel聚集(gather)写入

聚集写入( Gathering Writes)是指将多个 Buffer 中的数据“聚集”到 Channel。 特别注意:按照缓冲区的顺序,写入 position 和 limit 之间的数据到 Channel 。 

Channel分散(scatter)读取

分散读取( Scattering Reads)是指从 Channel 中读取的数据“分散” 到多个 Buffer 中。 特别注意:按照缓冲区的顺序,从 Channel 中读取的数据依次将 Buffer 填满。

 

聚集写入( Gathering Writes和分散读取( Scattering Reads)代码示例

1 package com.expgiga.NIO;  2   3 import java.io.FileInputStream;  4 import java.io.FileOutputStream;  5 import java.io.IOException;  6 import java.io.RandomAccessFile;  7 import java.nio.ByteBuffer;  8 import java.nio.CharBuffer;  9 import java.nio.MappedByteBuffer; 10 import java.nio.channels.FileChannel; 11 import java.nio.charset.Charset; 12 import java.nio.charset.CharsetDecoder; 13 import java.nio.charset.CharsetEncoder; 14 import java.nio.file.Paths; 15 import java.nio.file.StandardOpenOption; 16 import java.util.Map; 17 import java.util.Set; 18  19 /** 20  * 一、Channel:用于源节点与目标节点之间的连接。在Java NIO中,负责缓冲区中数据传输,Channel本身不存储数据,因此需要配合缓冲区进行传输。 21  * 22  * 二、Channel的实现类: 23  *     java.nio.channels.Channel 接口: 24  *     |-- FileChannel 25  *     |-- SocketChannel 26  *     |-- ServerSocketChannel 27  *     |-- DatagramChannel 28  * 29  * 三、获取通道Channel 30  * 1.Java针对支持通道的类提供了getChannel()方法 31  *   本地IO 32  *   FileInputStream/FileOutputStream 33  *   RandomAccessFile 34  * 35  *   网络IO: 36  *   Socket 37  *   ServerSocket 38  *   DatagramSocket 39  * 40  * 2.在jdk1.7中的NIO.2针对各个通道提供了静态方法open() 41  * 42  * 3.在jdk1.7中的NIO.2的Files工具类的newByteChannel() 43  * 44  * 四、通道之间的数据传输 45  * transferFrom() 46  * transferTo() 47  * 48  * 五、分散(scatter)与聚集(gather) 49  * 分散读取(scattering Reads):将通道中的数据分散到多个缓冲区中 50  * 聚集写入(gathering Writes):将多个缓冲区的数据聚集到通道中 51  * 52  * 六、字符集Charset 53  * 编码:字符串->字节数组 54  * 解码:字节数组 -> 字符串 55  * 56  */ 57 public class TestChannel { 58  59     public static void main(String[] args) throws IOException { 60  61         /* 62          * 1.利用通道完成文件的复制(非直接缓冲区) 63          */ 64         FileInputStream fis = null; 65         FileOutputStream fos = null; 66  67         FileChannel inChannel = null; 68         FileChannel outChannel = null; 69  70         try { 71             fis = new FileInputStream("1.jpg"); 72             fos = new FileOutputStream("2.jpg"); 73             //1.获取通道 74             inChannel = fis.getChannel(); 75             outChannel = fos.getChannel(); 76  77             //2.分配指定大小的缓冲区 78             ByteBuffer buffer = ByteBuffer.allocate(1024); 79  80             //3.将通道中的数据缓冲区中 81             while (inChannel.read(buffer) != -1) { 82  83                 buffer.flip();//切换成都数据模式 84  85                 //4.将缓冲区中的数据写入通道中 86                 outChannel.write(buffer); 87                 buffer.clear();//清空缓冲区 88             } 89         } catch (Exception e) { 90             e.printStackTrace(); 91         } finally { 92             if (outChannel != null) { 93                 try { 94                     outChannel.close(); 95                 } catch (IOException e) { 96                     e.printStackTrace(); 97                 } 98             } 99 100             if (inChannel != null) {101                 try {102                     inChannel.close();103                 } catch (IOException e) {104                     e.printStackTrace();105                 }106             }107 108             if (fis != null) {109                 try {110                     fis.close();111                 } catch (IOException e) {112                     e.printStackTrace();113                 }114             }115 116             if (fos != null) {117                 try {118                     fos.close();119                 } catch (IOException e) {120                     e.printStackTrace();121                 }122             }123         }124 125 126         /*127          * 2.利用(直接缓冲区)通道完成文件的复制(内存映射文件的方式)128          */129 130         long start = System.currentTimeMillis();131         FileChannel inChannel2 = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);132         FileChannel outChannel2 = FileChannel.open(Paths.get("3.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);133 134         //内存映射文件135         MappedByteBuffer inMappedBuf = inChannel2.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());136         MappedByteBuffer outMappedBuf = outChannel2.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size());137 138         //直接对缓冲区进行数据读写操作139         byte[] dst = new byte[inMappedBuf.limit()];140         inMappedBuf.get(dst);141         outMappedBuf.put(dst);142 143         inChannel2.close();144         outChannel2.close();145 146         long end = System.currentTimeMillis();147         System.out.println("耗费的时间为:" + (end - start));148 149         /*150          * 通道之间的数据传输(直接缓冲区)151          */152         FileChannel inChannel3 = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);153         FileChannel outChannel3 = FileChannel.open(Paths.get("3.jpg"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);154 155         inChannel3.transferTo(0, inChannel3.size(), outChannel3);156         //等价于157 //        outChannel3.transferFrom(inChannel3, 0, inChannel3.size());158 159         inChannel3.close();160         outChannel3.close();161 162         /*163          * 分散和聚集164          */165         RandomAccessFile randomAccessFile1 = new RandomAccessFile("1.txt", "rw");166 167         //1.获取通道168         FileChannel fileChannel1 = randomAccessFile1.getChannel();169 170         //2.分配指定大小的缓冲区171         ByteBuffer buf1 = ByteBuffer.allocate(100);172         ByteBuffer buf2 = ByteBuffer.allocate(2014);173 174         //3.分散读取175         ByteBuffer[] bufs = {buf1, buf2};176         fileChannel1.read(bufs);177 178         for (ByteBuffer byteBuffer : bufs) {179             byteBuffer.flip();180         }181         System.out.println(new String(bufs[0].array(), 0, bufs[0].limit()));182         System.out.println("----------------------------");183         System.out.println(new String(bufs[1].array(), 0, bufs[1].limit()));184 185         //4.聚集写入186         RandomAccessFile randomAccessFile2 = new RandomAccessFile("2.txt", "rw");187         FileChannel fileChannel2 = randomAccessFile2.getChannel();188         fileChannel2.write(bufs);189 190 191         /*192          * 字符集193          */194         Map
map = Charset.availableCharsets();195 196 Set
> set = map.entrySet();197 198 for (Map.Entry
entry : set) {199 System.out.println(entry.getKey() + "=" + entry.getValue());200 }201 202 203 204 Charset cs1 = Charset.forName("GBK");205 //获取编码器和解码器206 CharsetEncoder ce = cs1.newEncoder();207 208 //获取解码器209 CharsetDecoder cd = cs1.newDecoder();210 211 CharBuffer cBuf = CharBuffer.allocate(1024);212 cBuf.put("hello world!");213 cBuf.flip();214 215 //编码216 ByteBuffer bBuf = ce.encode(cBuf);217 218 for (int i = 0; i < 12; i++) {219 System.out.println(bBuf.get());220 }221 222 //解码223 bBuf.flip();224 CharBuffer cBuf2 = cd.decode(bBuf);225 System.out.println(cBuf2.toString());226 227 System.out.println("----------------------------");228 Charset cs2 = Charset.forName("UTF-8"); //"GBK"229 bBuf.flip();230 CharBuffer cBuf3 = cs2.decode(bBuf);231 System.out.println(cBuf3);232 }233 }

 

转载地址:http://svoja.baihongyu.com/

你可能感兴趣的文章
JavaScript 数据类型
查看>>
量子通信和大数据最有市场突破前景
查看>>
StringBuilder用法小结
查看>>
对‘初学者应该选择哪种编程语言’的回答——计算机达人成长之路(38)
查看>>
如何申请开通微信多客服功能
查看>>
Sr_C++_Engineer_(LBS_Engine@Global Map Dept.)
查看>>
非监督学习算法:异常检测
查看>>
App开发中甲乙方冲突会闹出啥后果?H5 APP 开发可以改变现状吗
查看>>
jquery的checkbox,radio,select等方法总结
查看>>
Linux coredump
查看>>
Ubuntu 10.04安装水晶(Mercury)无线网卡驱动
查看>>
Myeclipes快捷键
查看>>
我的友情链接
查看>>
ToRPC:一个双向RPC的Python实现
查看>>
Vim脚本 - 竖线'|' 和反斜线'\'
查看>>
netty框架的学习笔记 + 一个netty实现websocket通信案例
查看>>
我的友情链接
查看>>
nginx在reload时候报错invalid PID number
查看>>
神经网络和深度学习-第二周神经网络基础-第二节:Logistic回归
查看>>
Myeclipse代码提示及如何设置自动提示
查看>>