java nio 之MappedByteBuffer
2009-11-20 21:02:09 来源:WEB开发网核心提示:其实掌握 MappedByteBuffer 并不难,只要记住“三方三法三特性”(我自己总结的,java nio 之MappedByteBuffer,呵呵 ~~ 不要扔鸡蛋哦,,就这么凑合吧,大家扔鸡蛋 ~~~) ! 1 MappedByteBuffer 的读取 / 写入文件和普通 I/O 流的对比 import jav
其实掌握 MappedByteBuffer 并不难,只要记住“三方三法三特性”(我自己总结的,呵呵 ~~ 不要扔鸡蛋哦。。。)这句话就可以轻松搞定! MappedByteBuffer 只是一种特殊的 ByteBuffer ,即是 ByteBuffer 的子类。 MappedByteBuffer 将文件直接映射到内存(这里的内存指的是虚拟内存,并不是物理内存,后面说证明这一点)。通常,可以映射整个文件,如果文件比较大的话可以分段进行映射,只要指定文件的那个部分就可以。而且,与 ByteBuffer 十分类似,没有构造函数(你不可 new MappedByteBuffer ()来构造一个 MappedByteBuffer ),我们可以通过 java.nio.channels.FileChannel 的 map() 方法来获取 MappedByteBuffer 。其实说的通俗一点就是 Map 把文件的内容被映像到计算机虚拟内存的一块区域,这样就可以直接操作内存当中的数据而无需操作的时候每次都通过 I/O 去物理硬盘读取文件,所以效率上有很大的提升!
三种方式:
FileChannel 提供了 map 方法来把文件影射为内存映像文件: MappedByteBuffer map(int mode,long position,long size); 可以把文件的从 position 开始的 size 大小的区域映射为内存映像文件, mode 指出了 可访问该内存映像文件的方式: READ_ONLY,READ_WRITE,PRIVATE.
a. READ_ONLY, (只读): 试图修改得到的缓冲区将导致抛出 ReadOnlyBufferException .(MapMode.READ_ONLY )
b. READ_WRITE (读 / 写): 对得到的缓冲区的更改最终将传播到文件;该更改对映射到同一文件的其他程序不一定是可见的。 ( MapMode.READ_WRITE )
c. PRIVATE (专用): 对得到的缓冲区的更改不会传播到文件,并且该更改对映射到同一文件的其他程序也不是可见的;相反,会创建缓冲区已修改部分的专用副本。 ( MapMode.PRIVATE )
三个方法:
a. fore(); 缓冲区是 READ_WRITE 模式下,此方法对缓冲区内容的修改强行写入文件
b. load() 将缓冲区的内容载入内存,并返回该缓冲区的引用
c. isLoaded() 如果缓冲区的内容在物理内存中,则返回真,否则返回假
三个特性:
调用信道的 map() 方法后,即可将文件的某一部分或全部映射到内存中,映射内存缓冲区是个直接缓冲区,继承自 ByteBuffer, 但相对于 ByteBuffer, 它有更多的优点:
a. 读取快
b. 写入快
c. 随时随地写入
口说无凭,俗话说的好,是金子是银子拿来炼一炼就知道 ( 也不知道有没有这么一句俗话,反正用到这还合适,就这么凑合吧,大家扔鸡蛋 ~~~) !
1 MappedByteBuffer 的读取 / 写入文件和普通 I/O 流的对比
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
public class MapMemeryBuffer {
public static void main(String[] args) throws Exception {
ByteBuffer byteBuf = ByteBuffer.allocate(1024 * 14 * 1024);
byte[] bbb = new byte[14 * 1024 * 1024];
FileInputStream fis = new FileInputStream("d:\\test");
FileOutputStream fos = new FileOutputStream("d:\\outFile.txt");
FileChannel fc = fis.getChannel();
long timeStar = System.currentTimeMillis();// 得到当前的时间
fc.read(byteBuf);//1 读取
long timeEnd = System.currentTimeMillis();// 得到当前的时间
System.out.println("Read time :" + (timeEnd - timeStar) + "ms");
timeStar = System.currentTimeMillis();
fos.write(bbb);// 写入
timeEnd = System.currentTimeMillis();
System.out.println("Write time :" + (timeEnd - timeStar) + "ms");
fos.flush();
fc.close();
fis.close();
}
}
输出结果:
Read time :1874ms
Write time :360ms
把上面的程序的 1 换成 MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fileLength);
2 换成 mbb.flip();
输出结果:
Read ByteBuf take time :16ms
Write ByteBuf take time :0ms
可见普通 I/O 和 MappedByteBuffer 是没法比的。另外在写入的时候花了 0ms 说明 Map 写入机制是根据你的更改量来决定,就是只保存修改部分的!
三种方式:
FileChannel 提供了 map 方法来把文件影射为内存映像文件: MappedByteBuffer map(int mode,long position,long size); 可以把文件的从 position 开始的 size 大小的区域映射为内存映像文件, mode 指出了 可访问该内存映像文件的方式: READ_ONLY,READ_WRITE,PRIVATE.
a. READ_ONLY, (只读): 试图修改得到的缓冲区将导致抛出 ReadOnlyBufferException .(MapMode.READ_ONLY )
b. READ_WRITE (读 / 写): 对得到的缓冲区的更改最终将传播到文件;该更改对映射到同一文件的其他程序不一定是可见的。 ( MapMode.READ_WRITE )
c. PRIVATE (专用): 对得到的缓冲区的更改不会传播到文件,并且该更改对映射到同一文件的其他程序也不是可见的;相反,会创建缓冲区已修改部分的专用副本。 ( MapMode.PRIVATE )
三个方法:
a. fore(); 缓冲区是 READ_WRITE 模式下,此方法对缓冲区内容的修改强行写入文件
b. load() 将缓冲区的内容载入内存,并返回该缓冲区的引用
c. isLoaded() 如果缓冲区的内容在物理内存中,则返回真,否则返回假
三个特性:
调用信道的 map() 方法后,即可将文件的某一部分或全部映射到内存中,映射内存缓冲区是个直接缓冲区,继承自 ByteBuffer, 但相对于 ByteBuffer, 它有更多的优点:
a. 读取快
b. 写入快
c. 随时随地写入
口说无凭,俗话说的好,是金子是银子拿来炼一炼就知道 ( 也不知道有没有这么一句俗话,反正用到这还合适,就这么凑合吧,大家扔鸡蛋 ~~~) !
1 MappedByteBuffer 的读取 / 写入文件和普通 I/O 流的对比
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
public class MapMemeryBuffer {
public static void main(String[] args) throws Exception {
ByteBuffer byteBuf = ByteBuffer.allocate(1024 * 14 * 1024);
byte[] bbb = new byte[14 * 1024 * 1024];
FileInputStream fis = new FileInputStream("d:\\test");
FileOutputStream fos = new FileOutputStream("d:\\outFile.txt");
FileChannel fc = fis.getChannel();
long timeStar = System.currentTimeMillis();// 得到当前的时间
fc.read(byteBuf);//1 读取
long timeEnd = System.currentTimeMillis();// 得到当前的时间
System.out.println("Read time :" + (timeEnd - timeStar) + "ms");
timeStar = System.currentTimeMillis();
fos.write(bbb);// 写入
timeEnd = System.currentTimeMillis();
System.out.println("Write time :" + (timeEnd - timeStar) + "ms");
fos.flush();
fc.close();
fis.close();
}
}
输出结果:
Read time :1874ms
Write time :360ms
把上面的程序的 1 换成 MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fileLength);
2 换成 mbb.flip();
输出结果:
Read ByteBuf take time :16ms
Write ByteBuf take time :0ms
可见普通 I/O 和 MappedByteBuffer 是没法比的。另外在写入的时候花了 0ms 说明 Map 写入机制是根据你的更改量来决定,就是只保存修改部分的!
Tags:java nio MappedByteBuffer
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接