内存映射文件时利用虚拟内存实现来将一个文件或者文件的一部分映射到内存中,然后整个文件就可以当作数组一样的访问,这个比传统的文件操作要快得多,Java
使用内存映射文件首先需要从文件中获取一个channel(通道),通道时磁盘文件的一个抽象,他使得我们可以访问诸如内存映射、文件加锁机制以及文件间快速数据传递等操作系统特性,然后通过调用
FileChannel
类的
map
方法从这个通道获取一个映射块(ByteBuffer),然后就可以读取/写入文件块内容,map 支持的模式有如下:

  • FileChannel.MapMode.READ_ONLY:所产生的缓冲区是只读的,如果对只读的缓冲区进行写操作,将会导致 ReadonlyBufferException 异常
  • FileChannel.MapMode.READ_WRITE:所产生的缓冲区是可写的,任何修改都会在某个时刻写回文件(写入不是及时的)
  • FileChannel.MapMode.PRIVATE:所产生的缓冲区是可写的,但是任何修改对这个缓冲区来说都是私有的,不会传播到文件中

映射文件示例代码:

  • 读取文件:

             Path filePath = Paths.get("D:\\我的游戏\\World of Warcraft\\Data\\data", "data.001");

             long startTime = System.currentTimeMillis(); //获取开始时间

            try {

                   try (FileChannel channel = FileChannel.open(filePath, StandardOpenOption.READ)) {

                           int size = 40960;

                           long readByteSize = 0;

                           ByteBuffer byteBuffer = ByteBuffer.allocate(size);

                           int readCount;

                            do {

                                     readCount = channel.read(byteBuffer);

                                     byte[] readBytes = new
    byte[byteBuffer.limit()];

                                   
    // channel.read 后其 position 是 readCount,因此需要读取数据时,需要重置 position = 0

                                    
    byteBuffer.position(0);

                                     for(int i=0;i< readBytes.length;i++){

                                            readBytes[i] = byteBuffer.get();

                                     }

                                     byteBuffer.clear();

                                   
    if (readCount != -1) {

                                           readByteSize += readCount;

                                   
     }

                                   
    System.out.print("readCount +" + readCount + " readByteSize " + readByteSize + " ");

                             } while (readCount != -1);

                    }

            } catch (IOException ex) {

                            ex.printStackTrace();

          
     }

            long endTime = System.currentTimeMillis(); //获取结束时间

            System.out.println("程序运行时间: " + (endTime - startTime) + "ms");

     
     

  • 写入文件(使用
    RandomAccessFile

    MappedByteBuffer):

                    Random random = new
    Random();

                    Path writeFilePath = Paths.get("d:\\channel.dat");

                    startTime = System.currentTimeMillis(); //获取开始时间

                    try {

                            byte[] buff = new
    byte[40960];

                            long position = 0;

                            long size = buff.length;

                            RandomAccessFile randomAccessFile = new
    RandomAccessFile(writeFilePath.toString(), "rw");

                            try (FileChannel outChannel = randomAccessFile.getChannel()) {

                                    for (int i = 0; i < 1000; i++) {

                                            random.nextBytes(buff);

                                            MappedByteBuffer buffer = outChannel.map(FileChannel.MapMode.READ_WRITE, position, size);

                                            buffer.put(buff);

                                            position += size;

                                    }

                            }

                    } catch (IOException ex) {

                            ex.printStackTrace();

                    }

                    endTime = System.currentTimeMillis(); //获取结束时间

                    System.out.println("程序运行时间: " + (endTime - startTime) + "ms");

     
     

笔记:I/O流-内存映射文件的更多相关文章

  1. 《Java核心技术卷二》笔记(二)文件操作和内存映射文件

    文件操作 上一篇已经总结了流操作,其中也包括文件的读写.文件系统除了读写以为还有很多其他的操作,如复制.移动.删除.目录浏览.属性读写等.在Java7之前,一直使用File类用于文件的操作.Java7 ...

  2. MemoryMappedFile 内存映射文件 msdn

    http://msdn.microsoft.com/zh-cn/library/dd997372%28v=vs.110%29.aspx 内存映射文件 .NET Framework 4.5 其他版本 1 ...

  3. C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转

    原文:C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing ...

  4. NET 4 中 内存映射文件

    原文链接 : http://blogs.msdn.com/salvapatuel/archive/2009/06/08/working-with-memory-mapped-files-in-net- ...

  5. Java编程的逻辑 (61) - 内存映射文件及其应用 - 实现一个简单的消息队列

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  6. C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped

    节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). 内存映射文件对于托管世界的开发人员来说似乎很陌生,但它确实已经是很远古的技术了,而且在操作 ...

  7. .NET 4.0中使用内存映射文件实现进程通讯

    操作系统很早就开始使用内存映射文件(Memory Mapped File)来作为进程间的共享存储区,这是一种非常高效的进程通讯手段.Win32 API中也包含有创建内存映射文件的函数,然而,这些函数都 ...

  8. 内存映射文件(Memory-Mapped File)

    Java Memory-Mapped File所使用的内存分配在物理内存而不是JVM堆内存,且分配在OS内核. 1: 内存映射文件及其应用 - 实现一个简单的消息队列 / 计算机程序的思维逻辑 在一般 ...

  9. JAVA I/O(三)内存映射文件

    <Java编程思想>中对内存映射文件有详细的介绍,此处仅做简单记录和总结.内存映射文件允许创建和修改因为太大而不能放入内存的文件. 1. 内存映射文件简单实例 import java.io ...

随机推荐

  1. byte[] Base64 Stream 之间相互转换

    图片 base64转byte[] /// <summary> /// 保存base64图片,返回阿里云地址 /// </summary> /// <param name= ...

  2. 腾讯云+校园扶持计划是bug还是福利

    前言   上午突然收到好友的微信消息.打开一看是关于关腾讯云"云+校园扶持计划".仔细看下了意思就是用户可以花360大洋购买腾讯云服务器配置为1核2G,1M带宽的服务器3年.(腾讯 ...

  3. windows2003服务器系统日志:查看电脑远程登录记录

    控制面板>>管理工具>>事件查看器>>选择安全性再点工具栏目中查看>>筛选>>事件ID填528进行过滤,时间你看是多久,双击查看之后就可以找 ...

  4. apache配置,禁止ip访问web站点

    由于一台服务器上面部署了好几个应用,对应不同的域名,如果用户知道ip地址的话,直接用户ip地址访问,会显示第一个虚拟主机的页面(更改了虚拟主机的顺序,每次都是显示第一个).这样对用户造成不好的印象,所 ...

  5. javascript 获取随机数

    javascript 获取随机数 var rand=Math.floor(Math.random()*(n+1)) floor 向下取整 random 获得0-1之间的随机数

  6. Linux查看网络的联机状态

    Linux查看网络的联机状态 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ netstat -a^C unix 3 [ ] 流 已连接 14923 @/tmp ...

  7. Logger之简单入门

    Java 中自带的日志系统,今天抽空了解了一点,算是入了门,所以将自己的一些心得记录下来,以备日后查看,有兴趣的朋友,看到此文章,觉得有错误或需要添加的地方,请在下方评论留言,大家可以共同进步,谢谢: ...

  8. 【BZOJ1499】瑰丽华尔兹(动态规划)

    [BZOJ1499]瑰丽华尔兹(动态规划) 题面 BZOJ 题解 先写部分分 设\(f[t][i][j]\)表示当前在\(t\)时刻,位置在\(i,j\)时走的最多的步数 这样子每一步要么停要么走 时 ...

  9. 【BZOJ3160】万径人踪灭(FFT,Manacher)

    [BZOJ3160]万径人踪灭(FFT,Manacher) 题面 BZOJ 题解 很容易想到就是满足条件的子序列个数减去回文子串的个数吧... 至于满足条件的子序列 我们可以依次枚举对称轴 如果知道关 ...

  10. 什么是Docker??

    ​​Docker是一个轻量级虚拟机,也是一种Linux容器,它突破了以往的沙盒技术,解放了应用部署,让PaaS的应用场景更为广泛. ​ docker是通过内核虚拟化技术((namespaces及cgr ...