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

    看似简单,但其实包含很多技巧思维 1.查询课程表中所有科目大于80的学生 select distinct name from student where name not in (select nam ...

  2. mongodb3.0分片及java代码连接操作测试(开启用户验证)

    最近抽时间搭建了一下mongodb简单的分片,整个过程还算是蛮顺利,只不过在用户验证这一块遇到了一些问题,好在最后终于搞定. 一.服务器搭建过程: 1.安装四个mongodb:一个作为config.一 ...

  3. PCI9054芯片的型号说明及购买建议

    个脚,这也是大部分人用到的:而"BI"结尾的是BGA封装的,225个脚,较少用到,对它不再多说. 这几种系列量产的时间如下: 年11月 年8月 年2月 年 年 年到2006年期间, ...

  4. 【mongodb系统学习之十一】mongodb删除数据

    十一.mongodb删除数据: 1).删除全部文档:remove,语法db.collectionName.remove({}):小括号里边必须要有条件,否则不成功:如果只是一个空的{},则会删除集合内 ...

  5. freemarker处理哈希表的内建函数

    freemarker处理哈希表的内建函数 1.简易说明 (1)map取值 (2)key取值 2.实现示例 <html> <head> <meta http-equiv=& ...

  6. 前端框架Vue入门

    1.Vue简介 Vue是一套构建用户界面的渐进性框架.Vue采用自底向上增量开发的设计,其关注点在图层,与angular的区别就在这里,它关注的是图层,而angular注释的是数据. 2.与React ...

  7. C# 获取一个独一无二的字符串 GUID

    在保存文件,创建目录时,为了保证名称不重复,经常使用Random产生一个随机数,有更简单且不会重复的办法是: Guid.NewGuid().ToString() 就会生成一个类似 37c1acec-4 ...

  8. 复制粘贴之插件(clipboard.min.js)不需要安装flash

    <!DOCTYPE html> <html> <head> <title>ZeroClipboard Test</title> <me ...

  9. 【原】Spring Boot 配置swagger2没有文档解决方案

    @Bean public Docket customImplementation(){ return new Docket(DocumentationType.SWAGGER_2) .select() ...

  10. TCP/IP资料整理

    一.概念 1. TCP/IP常见帧格式 2. 详解网络嗅探工具的原理 二.API 1. Linux kernel tcp 连接建立详解——由listen系统调用的backlog参数引发的长篇大论