关于ByteBuffer、MappedByteBuffer类学习

来源:互联网 发布:罗马共和国知乎 编辑:程序博客网 时间:2024/05/22 05:13
最近公司有个小项目要放在springboot里让我改造下,里面有MappedByteBuffer所以百度+自己看代码学习了一下,记录下,防止忘了

MappedByteBuffer继承ByteBuffer,ByteBuffer是个缓冲区方便自己的IO操作而MappedByteBuffer是java nio引入的文件内存映射方案,读写性能极高。大文件用缓存区的话用这个,具体的还没深入研究,先学习下用法。

ByteBuff学习:
简单事例:实现文件的复制

public class MappedByteBufferTest {    public static void main(String[] args) {        ByteBuffer buff = ByteBuffer.allocate(128);        FileChannel fin = null;        FileChannel fout = null;        try{            fin = new FileInputStream("E:"+File.separator+"test"+File.separator+"redis-4.0.1.tar.gz").getChannel();            fout = new FileOutputStream("E:"+File.separator+"test1"+File.separator+"redis-4.0.1.tar.gz").getChannel();            while(fin.read(buff) != -1) {                buff.flip();                fout.write(buff);                buff.clear();            }        }catch (Exception e) {            e.printStackTrace();        }finally {            try {                if(fin != null) {                    fin.close();                }                if(fout != null) {                    fout.close();                }            } catch(IOException e) {                e.printStackTrace();            }        }    }}

ByteBuffer buff = ByteBuffer.allocate(128);开辟一个缓冲区,然后我们可以在这个缓冲区里进行一些操作。
ByteBuffer 有4个索引mark,position,limit,capacity

mark用于对当前position的标记(allocate后-1)

position表示当前可读写的指针,就是你要读写的位置,读写玩都往后加1

limit是可以读写的边界,相当于记录用到了缓存的哪个位置,ByteBuffer.allocate(128)后在128这个位置,如果用了100调用buff.flip()后那么他变到100这个位置。然后你就可以读到这个位置就知道读完了。

capacity是这个ByteBuffer的容量,如上就是128

ByteBuffer buff = ByteBuffer.allocate(128);
开辟缓存区时: mark : -1 ,position :0,limit :128,capacity:128
开始写入数据position随着写移动位置
写完
buff.flip();方法:

    public final Buffer flip() {        limit = position;        position = 0;        mark = -1;        return this;    }

这里向缓存区写入字节后,你要开始使用缓存区时调用,如上将limit放到读到的位置,position置0;

使用一次后你要重复使用这个缓存区就要掉 buff.clear()方法:

    public final Buffer clear() {        position = 0;        limit = capacity;        mark = -1;        return this;    }

一切回到初始化状态然后使用

这里写图片描述

MappedByteBuffer 学习:
MappedByteBuffer 继承 ByteBuffer
简单事例:

1读取文件:

package com.zzm.test;import java.io.File;import java.io.FileInputStream;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.nio.charset.Charset;public class MappedByteBufferTest2 {    private final static Charset charset = Charset.forName("GBK");     public static void main(String[] args) {        try {            FileInputStream fis = new FileInputStream("E:"+File.separator+"test"+File.separator+"123.txt");            FileChannel fc = fis.getChannel();            MappedByteBuffer mbb = fis.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fc.size());               fis.close();            fc.close();            String str = charset.decode(mbb).toString();            System.out.println(str);        } catch (Exception e) {            e.printStackTrace();        }    }}

2实现文件的复制

package com.zzm.test;import java.io.File;import java.io.FileInputStream;import java.nio.ByteBuffer;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;public class MappedByteBufferTest3 {    public static void main(String[] args) {        try {            FileInputStream fis = new FileInputStream("E:"+File.separator+"test"+File.separator+"123.txt");            FileChannel fc = fis.getChannel();            MappedByteBuffer mbb = fis.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fc.size());               fis.close();            fc.close();            System.out.println(mbb.capacity());            System.out.println(mbb.limit());            System.out.println(mbb.position());            //mbb.flip();            System.out.println(mbb.hasArray());            System.out.println(mbb.capacity());            System.out.println(mbb.limit());            System.out.println(mbb.position());            byte[] bytes = new byte[mbb.limit()];            ByteBuffer bb = mbb.get(bytes);            System.out.println(new String(bytes,"GBK"));        } catch (Exception e) {            e.printStackTrace();        }    }}

MappedByteBuffer mbb = fis.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fc.size());相当于开辟缓存区并将文件放进去,然后我们就可以进行一些列的操作。

原创粉丝点击