Java基础-虚拟内存之映射字节缓冲区(MappedByteBuffer)
Java基础-虚拟内存之映射字节缓冲区(MappedByteBuffer)
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.映射字节缓冲区
1>.什么是虚拟内存
答:虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。目前,大多数操作系统都使用了虚拟内存,如Windows家族的“虚拟内存”;Linux的“交换空间”等。
2>.什么是映射字节缓冲区
答:映射字节缓冲区,说白了就是Java将磁盘中的文件映射到内存中,然后通过修改内存的数据,从而间接修改了磁盘中的文件。这样做的目的就是为了快速对磁盘中的文件就行修改操作,将原来在磁盘上的I/O操作转换成了内存的I/O操作!
3>.Java代码案例展示
准备文件数据如下:
执行以下代码:
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.nio; 7 8 import java.io.RandomAccessFile; 9 import java.nio.MappedByteBuffer; 10 import java.nio.channels.FileChannel; 11 12 public class MyMapFileBuffer { 13 public static void main(String[] args) throws Exception { 14 testMapFileBuffer(); 15 } 16 17 public static void testMapFileBuffer() throws Exception { 18 //随机访问文件 19 RandomAccessFile raf = new RandomAccessFile("D:\\BigData\\JavaSE\\yinzhengjieData\\1.txt" , "rw") ; 20 //源文件通道,由于我们的raf对象是随机访问文件,因此我们就通过它来进行读写操作。 21 FileChannel fc = raf.getChannel(); 22 23 //调用FileChannel的映射功能,指定映射模式为读写,指定映射的其实位置是0,结束位置是3(不包含3),因此我们只能修改索引为0,1,2的映射字符,如果超出映射范围就会抛异常:BufferOverflowException 24 MappedByteBuffer buf = fc.map(FileChannel.MapMode.READ_WRITE , 0 , 3) ; 25 buf.put((byte)89) ; 26 buf.put((byte)73) ; 27 buf.put((byte)78) ; 28 System.out.println("修改完成!"); 29 } 30 } 31 32 /* 33 以上代码输出结果如下: 34 修改完成! 35 */
查看磁盘中文件内容如下:
二.向文件写入10w次数据,使用RandomAccessFile方式和MappedByteBuffer方式对比性能
尹正杰
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.nio; 7 8 import java.io.RandomAccessFile; 9 import java.nio.MappedByteBuffer; 10 import java.nio.channels.FileChannel; 11 12 public class MyMapFileBuffer { 13 final static byte[] data = {89,73,78}; 14 15 public static void main(String[] args) throws Exception { 16 testMapFileBuffer(); 17 testRandomAccessFile(); 18 } 19 20 public static void testRandomAccessFile() throws Exception{ 21 //随机访问文件 22 RandomAccessFile raf = new RandomAccessFile("D:\\BigData\\JavaSE\\yinzhengjieData\\1.txt" , "rw") ; 23 long start = System.currentTimeMillis(); 24 for (int i=0 ;i<100000;i++){ 25 raf.write(data); 26 //每次写完数据将文件指针回到原点 27 raf.seek(0); 28 } 29 long end = System.currentTimeMillis(); 30 System.out.printf("RandomAccessFile 方式写入10万次数据需要用时为:[%d]\n",(end-start)); 31 } 32 33 34 public static void testMapFileBuffer() throws Exception { 35 //随机访问文件 36 RandomAccessFile raf = new RandomAccessFile("D:\\BigData\\JavaSE\\yinzhengjieData\\1.txt" , "rw") ; 37 //源文件通道,由于我们的raf对象是随机访问文件,因此我们就通过它来进行读写操作。 38 FileChannel fc = raf.getChannel(); 39 40 //调用FileChannel的映射功能,指定映射模式为读写,指定映射的其实位置是0,结束位置是3(不包含3),因此我们只能修改索引为0,1,2的映射字符,如果超出映射范围就会抛异常:BufferOverflowException 41 MappedByteBuffer buf = fc.map(FileChannel.MapMode.READ_WRITE , 0 , 3) ; 42 long start = System.currentTimeMillis(); 43 for (int i=0;i<100000;i++){ 44 //往虚拟内存中写入数据 45 buf.put(data); 46 //启用整个容量 47 buf.clear(); 48 } 49 long end = System.currentTimeMillis(); 50 System.out.printf("MapFileBuffer 方式写入10万次数据需要用时为:[%d]\n",(end-start)); 51 } 52 } 53 54 /* 55 以上代码输出结果如下: 56 MapFileBuffer 方式写入10万次数据需要用时为:[7] 57 RandomAccessFile 方式写入10万次数据需要用时为:[196] 58 */
本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/9256801.html,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费)
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。