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

    PLSQL介绍 PLSQL是Oracle对SQL99的一种扩展,基本每一种数据库都会对SQL进行扩展,Oracle对SQL的扩展就叫做PLSQL... SQL99是什么 (1)是操作所有关系型数据库的 ...

  2. Linux基础三

    cat:查看全部(缺点:内容较多时不方便查看) 格式:cat [选项] 文件名 常用命令选项 -n:在每一行前加上行号 [root@localhost 桌面]# cat -n /etc/passwd ...

  3. 【前端】HTML中最适合做按钮的元素

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/6405914.html 可选的可以做按钮的元素有如下几个 a.input.button.div(span等) 场景 ...

  4. Windows2003查看远程桌面连接的用户

    要查看通过远程连接windows2003的用户,则打开任务管理器,切换到“用户”选项卡上进行查看.

  5. PHP stream_context_create()作用和用法分析

    stream_content_create 创建并返回一个文本数据流并应用各种选项,可用于fopen(),filegetcontents()等过程的超时设置.代理服务器.请求方式.头信息设置的特殊过程 ...

  6. 【javascript】jQuery判断用户右击事件

    jquery 判断用户是鼠标是右击还是左击, // 1 = 鼠标左键 left; 2 = 鼠标中键; 3 = 鼠标右键 $(document).mousedown(function(e) { if(3 ...

  7. VxWorks 基本启动方式

    VxWorks 基本启动方式     按VxWorks内核的下载形式,VxWorks启动总体上分为两种方式:下载型和ROM 型.     @下载型启动方式:bootrom+VxWorks.此时boot ...

  8. Netty的并发编程实践3:CAS指令和原子类

    互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能的额外损耗,因此这种同步被称为阻塞同步,它属于一种悲观的并发策略,我们称之为悲观锁.随着硬件和操作系统指令集的发展和优化,产生了非阻塞同步,被称为 ...

  9. Java获取某年某季度的第一天出错

    1.错误描述 Exception in thread "main" java.lang.IllegalArgumentException: Cannot format given ...

  10. app_offline.htm的作用

    如果你要COPY站点,进行站点维护,部署,和进行大量修改,有可能要停掉你的WEB应用程序了,而以一个友好的方式提示给用户,比如什么"本网站正在更新"等等的信息可以建立一个叫app_ ...