博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NIO系列——通道(Channel)
阅读量:6947 次
发布时间:2019-06-27

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

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

 

转载于:https://www.cnblogs.com/dreamHighMjc/p/8185228.html

你可能感兴趣的文章
九度OJ 1068 球半径和数量 (模拟)
查看>>
了解如何高速嵌入式?
查看>>
HDU4960Another OCD Patient(间隙dp,后座DP)
查看>>
Spark on Yarn遇到的问题及解决思路
查看>>
swift知识点 [1]
查看>>
(转载)北上广深房价只会涨不会降
查看>>
移动存储卡仍然用FAT32文件系统的真相
查看>>
lambda 2
查看>>
windows下配置nginx+php环境
查看>>
Python批量读取人脸图片与数据互相转换
查看>>
android 75 新闻列表页面
查看>>
用数据说话:北京房价数据背后的数据
查看>>
Java系列笔记(4) - JVM监控与调优
查看>>
ITK 4.8.1 Qt 5.4 MinGW 4.9.1 Configuration 配置
查看>>
短网址算法原理
查看>>
kvm 性能调优
查看>>
OC 实例变量(Instance Var)和成员变量(member var)区别
查看>>
hdu 1542 Atlantis 段树区,并寻求,,,尼玛真坑人数据,不要打开一小阵!
查看>>
ssh 登录出现的几种错误以及解决办法
查看>>
Win7 OpenCV 3.0.0 VS2013 环境配置
查看>>