内存映射文件时利用虚拟内存实现来将一个文件或者文件的一部分映射到内存中,然后整个文件就可以当作数组一样的访问,这个比传统的文件操作要快得多,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. shell 脚本——判断条件

    在之前的shell语言学习笔记中已经写过shell的几种判断语句及循环语句,也简单的介绍了shell语言判断语句和判断条件.在此再做进一步学习. test命令的测试功能 test命令用于检测系统文件及 ...

  2. Innotop简单介绍

      Innotop介绍 Innotop是一款Perl脚本编写.开源.功能强大的MySQ的监控工具,它通过文本模式(命令行模式)监控,功能强大,配置简单,易于使用等等特性.Innotop这个项目位于ht ...

  3. hi3531 SDK 编译 uboot, 修改PHY地址, 修改 uboot 参数 .

    一,编译uboot SDK文档写得比较清楚了,写一下需要注意的地方吧. 1. 之前用SDK里和别人给的已经编译好的uboot,使用fastboot工具都刷不到板子上.最后自己用SDK里uboot源码编 ...

  4. Windows Developer Day Review

    北京时间 3 月 8 日凌晨 1 点钟,今年的第一次 Windows Developer Day 正式召开.    因为时间太晚看不了直播,我也是第二天早上在公司看的重播.整个会议过程有很多值得去研究 ...

  5. iOS - UIView 动画

    1.UIView 动画 核心动画 和 UIView 动画 的区别: 核心动画一切都是假象,并不会真实的改变图层的属性值,如果以后做动画的时候,不需要与用户交互,通常用核心动画(转场). UIView ...

  6. ASP.NET Core 2.0 : 系列目录

    目录: ASP.NET Core 2.0 : 一. 概述 ASP.NET Core 2.0: 二. 开发环境 ASP.NET Core 2.0 : 三. 项目结构 ASP.NET Core 2.0 : ...

  7. 我在微信小程序遇到的坑

    这段时间刚好结束一个小程序,被坑的好惨,所以罗列出来,有用的着的,就抱走吧! 1.关于音频,项目要求能在退出小程序的情况下继续播放,所以我直接用了     wx.getBackgroundAudioM ...

  8. centos svn 服务器间的数据迁移

    svnadmin dump erp > ~/erp.svn   当前目录下的erp 导出到根目录下名为erp.svn tar -zcvf backupSvn.tar.gz backupSvn   ...

  9. 【BZOJ2882】工艺(后缀数组)

    [BZOJ2882]工艺(后缀数组) 题面 BZOJ权限题,我爱良心洛谷 题解 最容易的想法: 把字符串在后面接一份 然后求后缀数组就行了... #include<iostream> #i ...

  10. [CF940F]Machine Learning

    codeforces 一句话题意 求区间数字出现次数的mex,带修改 sol 带修膜队不解释 带修膜队的排序! struct query{ int id,l,r,t; bool operator &l ...