您的位置:首页 > 移动开发

关于ByteBuffer、MappedByteBuffer类学习

2017-10-20 17:30 411 查看
最近公司有个小项目要放在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());

a02f
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());相当于开辟缓存区并将文件放进去,然后我们就可以进行一些列的操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: