【Java nio】Channel

  1 package com.slp.nio;
  2 
  3 import org.junit.Test;
  4 
  5 import java.io.*;
  6 import java.nio.ByteBuffer;
  7 import java.nio.CharBuffer;
  8 import java.nio.MappedByteBuffer;
  9 import java.nio.channels.FileChannel;
 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.Set;
 18 
 19 /**
 20  * Created by sanglp on 2017/3/1.
 21  * 一、通道:用于源节点与目标节点的连接,在Java NIO中负责缓冲区中数据的传输。通道本身是不存储任何数据的,因此需要配合缓冲区进行传输数据
 22  * 二、通道的一些主要实现类
 23  * java.nio.Channel接口
 24  *     |--FileChannel
 25  *     |--SocketChannel
 26  *     |--ServerSocketChannel
 27  *     |--DatagramChannel
 28  * 三、获取通道
 29  * 1.java针对支持通道的类提供了getChannel()方法
 30  *     本地IO:
 31  *     FileInputStream/FileOutputStream/RandomAccessFile
 32  *     网络IO:
 33  *     Socket
 34  *     ServerSocket
 35  *     DategramSocket
 36  * 2.在jdk1.7中的NIO2针对各个通道提供了一个静态方法open()
 37  * 3。jdk1.7中的NIO2的Files工具类的newByteChannel()
 38  * 四、通道之间的数据传输
 39  * transferFrom()
 40  * transferTo()
 41  * 五、分散和聚集
 42  * 分散度区:将通道中的数据分散到多个缓冲区中
 43  * 聚集写入:将多个缓冲区中的数据聚集到通道中
 44  *
 45  * 六、字符集:Charset
 46  * 编码:字符串->字节数组
 47  * 解码:字节数组->字符串
 48  */
 49 public class TestChannel {
 50     @Test
 51     public void test6() throws CharacterCodingException {
 52         Charset cs1 =  Charset.forName("GBK");
 53         //获取编码器和解码器
 54         CharsetEncoder ce = cs1.newEncoder();
 55         //获取解码器
 56         CharsetDecoder cd = cs1.newDecoder();
 57 
 58         CharBuffer charBuffer = CharBuffer.allocate(1024);
 59         charBuffer.put("桑丽平加油!!");
 60         charBuffer.flip();
 61 
 62         //编码
 63         ByteBuffer byteBuffer = ce.encode(charBuffer);
 64         for (int i=0;i<12;i++){
 65             System.out.println(byteBuffer.get(i));
 66         }
 67 
 68         //解码
 69         byteBuffer.flip();
 70       CharBuffer charBuffer1 =   cd.decode(byteBuffer);
 71         System.out.println(charBuffer1.toString());
 72 
 73         System.out.println("------------------------");
 74 
 75         Charset cs2 = Charset.forName("UTF-8");
 76         byteBuffer.flip();
 77         CharBuffer  cBuf3 =cs2.decode(byteBuffer);
 78         System.out.println(cBuf3.toString());
 79     }
 80 
 81     @Test
 82     public void test5(){
 83         Map<String,Charset> map=Charset.availableCharsets();
 84         Set<Map.Entry<String,Charset>> set = map.entrySet();
 85        for (Map.Entry<String,Charset> entry :set ){
 86            System.out.println(entry.getKey()+"="+entry.getValue());
 87        }
 88     }
 89     @Test
 90     public void test4() throws IOException {
 91         RandomAccessFile randomAccessFile = new RandomAccessFile("1.txt","rw");
 92         //获取通道
 93         FileChannel channel = randomAccessFile.getChannel();
 94         //分配指定大小的缓冲区
 95         ByteBuffer buffer1 = ByteBuffer.allocate(100);
 96         ByteBuffer buffer2 = ByteBuffer.allocate(1024);
 97         //分散读取
 98         ByteBuffer [] bufs = {buffer1,buffer2};
 99         channel.read(bufs);
100         for (ByteBuffer byteBuffer:bufs){
101             byteBuffer.flip();
102         }
103 
104         System.out.println(new String(bufs[0].array(),0,bufs[0].limit()));
105         System.out.println("---------------");
106         System.out.println(new String(bufs[1].array(),0,bufs[1].limit()));
107 
108         //聚集写入
109         RandomAccessFile randomAccessFile1 = new RandomAccessFile("2.txt","rw");
110         FileChannel channel1 = randomAccessFile1.getChannel();
111         channel1.write(bufs);
112 
113     }
114 
115     //通道之间的数据传输(直接缓冲区)
116     @Test
117     public void test3() throws IOException {
118         FileChannel fileChannel = FileChannel.open(Paths.get("pipe.bmp"), StandardOpenOption.READ);
119         FileChannel outChannel =FileChannel.open(Paths.get("4.bmp"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
120 
121         fileChannel.transferTo(0,fileChannel.size(),outChannel);
122         //outChannel.transferFrom(fileChannel,0,fileChannel.size());或者
123         fileChannel.close();
124         outChannel.close();
125     }
126 
127     //2、利用直接缓冲区完成文件的复制(内存映射文件)
128     @Test
129     public void test2() throws IOException {
130         FileChannel fileChannel = FileChannel.open(Paths.get("pipe.bmp"), StandardOpenOption.READ);
131         FileChannel outChannel =FileChannel.open(Paths.get("3.bmp"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
132         //内存映射文件
133         MappedByteBuffer imMappedBuf = fileChannel.map(FileChannel.MapMode.READ_ONLY,0,fileChannel.size());
134         MappedByteBuffer outMappedBuf = outChannel.map(FileChannel.MapMode.READ_WRITE,0,fileChannel.size());
135         //直接对缓冲区进行数据的读写操作
136         byte [] dst = new byte[imMappedBuf.limit()];
137         imMappedBuf.get(dst);
138         outMappedBuf.put(dst);
139 
140         fileChannel.close();
141         outChannel.close();
142 
143     }
144 
145     //1、利用通道完成文件的复制(费直接缓冲区)
146     @org.junit.Test
147     public void test1(){
148         FileInputStream fis =null;
149         FileOutputStream fos =null;
150         FileChannel inChanne=null;
151         FileChannel outChannel=null;
152         try{
153        fis = new FileInputStream("pipe.bmp");
154         fos = new FileOutputStream("2.jpg");
155         //获取通道
156         inChanne =fis.getChannel();
157         outChannel = fos.getChannel();
158         //分配指定大小的缓冲区
159         ByteBuffer buffer = ByteBuffer.allocate(1024);
160         //将通道中的数据存入缓冲区中
161         while (inChanne.read(buffer)!=-1) {
162             buffer.flip();//切换为读取数据的模式
163             //将缓冲区中的数据写入通道
164             outChannel.write(buffer);
165             buffer.clear();//清空缓冲区
166         }
167     }catch (IOException e){
168         e.printStackTrace();
169     }finally {
170         if(outChannel!=null){
171             try {
172                 outChannel.close();
173             } catch (IOException e) {
174                 e.printStackTrace();
175             }
176         }
177         if(inChanne!=null){
178             try {
179                 inChanne.close();
180             } catch (IOException e) {
181                 e.printStackTrace();
182             }
183         }
184 
185         if(fis!=null){
186             try {
187                 fis.close();
188             } catch (IOException e) {
189                 e.printStackTrace();
190             }
191         }
192         if(fos!=null){
193             try {
194                 fos.close();
195             } catch (IOException e) {
196                 e.printStackTrace();
197             }
198         }
199     }
200 
201     }
202 }
原文地址:https://www.cnblogs.com/dream-to-pku/p/6505530.html