缓冲区和通道

一、通道(Channel): 用于源节点与目标节点的连接。在Java NIO中负责缓冲区中数据的传输。Channel本身不存储数据,因此需要配合和缓冲区进行传输。

二、通道的主要实现类

  • java.nio.channels.Channel 接口:
  • FileChannel
  • SocketChannel
  • SeverSocketChannel
  • DatagramChannel

三、获取通道

1.Java针对支持通道的类提供了getChannel()方法

  •  本地IO:
    
  •      FileInputStream/FileOutputStram
    
  •      RandomAccessFile
    
  •  网络IO:
    
  •      Socket
    
  •      ServerSocket
    
  •      DatagramSocket
    

2.在jdk1.7中的NIO.2针对各个通道提供了静态方法open()
3.在jdk1.7中的NIO.2的Files工具类的newByteChannel()

四、通道之间的数据传输

  • transferFrom()
  • transferTo()

五、分散(Scatter)与聚集(Getter)

  • 分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区中
  • 聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到通道中

六、字符集:Charset

  • 编码:将字符串转换成字节数组
  • 解码:将字节数组转换成字符串
public class TestChannel {
    //1.利用通道完成文件的复制(非直接缓冲区)
    @Test
    public void test1()  {
        FileInputStream fis= null;
        FileOutputStream fos= null;
        FileChannel inchannel = null;
        FileChannel outchannel = null;
        try {
            fis = new FileInputStream("背景图.jpg");
            fos = new FileOutputStream("背景图1.jpg");
            //① 获取通道
            inchannel = fis.getChannel();
            outchannel = fos.getChannel();
            //② 分配一个指定大小的缓区域
            ByteBuffer buf=ByteBuffer.allocate(1024);
            //③ 将通道中的数据写入缓冲区
            while (inchannel.read(buf)!=-1){
                buf.flip();//切换读取数据的模式
                //④ 将缓冲区的数据写入通道
                outchannel.write(buf);
                buf.clear();//清空缓冲区
            }
        } catch (IOException 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(fis!=null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fos!=null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

    //利用直接缓冲区完成文件的复制(内存映射文件)
    @Test
    public void test2()  {
        FileChannel inchannel = null;
        FileChannel outchannel = null;
        try {
            inchannel = FileChannel.open(Paths.get("背景图.jpg"), StandardOpenOption.READ);
            outchannel = FileChannel.open(Paths.get("背景图78.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
            //内存映射文件
            MappedByteBuffer inmap = inchannel.map(FileChannel.MapMode.READ_ONLY, 0, inchannel.size());
            MappedByteBuffer outmap = outchannel.map(FileChannel.MapMode.READ_WRITE, 0, inchannel.size());
            //直接对缓冲区进行数据的读写操作
            byte[] dst=new byte[inmap.limit()];
            ByteBuffer byteBuffer1 = inmap.get(dst);
            ByteBuffer byteBuffer2 = outmap.get(dst);
        } 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 test3() throws IOException {
        FileChannel inchannel = FileChannel.open(Paths.get("背景图.jpg"), StandardOpenOption.READ);
        FileChannel outchannel = FileChannel.open(Paths.get("背景图3.jpg"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
        inchannel.transferTo(0,inchannel.size(),outchannel);
        inchannel.close();
        outchannel.close();
    }
    //分散与聚集
    @Test
    public void test4() throws IOException {
        RandomAccessFile raf1 = new RandomAccessFile("1.txt", "rw");
        //1.获取通道
        FileChannel channel1 = raf1.getChannel();
        //2.分配指定大小的缓冲区
        ByteBuffer buffer1=ByteBuffer.allocate(100);
        ByteBuffer buffer2=ByteBuffer.allocate(1024);
        //3.分散读取
        ByteBuffer[] buffers={buffer1,buffer2};
        channel1.read(buffers);
        for (ByteBuffer bytebuffer: buffers
             ) {
            bytebuffer.flip();

        }
        System.out.println(new String(buffers[0].array(), 0, buffers[0].limit()));
        System.out.println(("-----------------"));
        System.out.println(new String(buffers[1].array(), 0, buffers[1].limit()));
        //4.聚集写入
        RandomAccessFile raf2=new RandomAccessFile("3.txt","rw");
        FileChannel channel2=raf2.getChannel();
        channel2.write(buffers);
        channel1.close();
        channel2.close();


    }
    //字符集
    @Test
    public void test6() throws CharacterCodingException {
        Charset gbk = Charset.forName("GBK");
        //获取编码器
        CharsetEncoder encoder = gbk.newEncoder();
        //获取解码器
        CharsetDecoder decoder = gbk.newDecoder();

        CharBuffer charBuffer = CharBuffer.allocate(1024);
        charBuffer.put("卢本伟牛逼");
        charBuffer.flip();
        //编码
        ByteBuffer byteBuffer = encoder.encode(charBuffer);
        for (int i = 0; i < 10; i++) {
            System.out.println(byteBuffer.get());
        }
        //解码
        byteBuffer.flip();
        CharBuffer charBuffer1 = decoder.decode(byteBuffer);
        System.out.println(charBuffer1.toString());

    }
    @Test
    public void test5(){
        Map< String, Charset > map = Charset.availableCharsets();
        Set< Map.Entry< String, Charset > > set = map.entrySet();
        set.stream().forEach(System.out::println);

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值