笔记:I/O流-内存映射文件

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

    ?
    ?

时间: 2024-10-25 18:56:12

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

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

文件操作 上一篇已经总结了流操作,其中也包括文件的读写.文件系统除了读写以为还有很多其他的操作,如复制.移动.删除.目录浏览.属性读写等.在Java7之前,一直使用File类用于文件的操作.Java7提供了Path,Paths,Files,FileSystem等类,使文件操作变得简单和全面.此外还有很多第三方库也提供了文件操作的便捷类如common.io中的FileUtils类,Ant api提供的FileSet等类. 1.File类的使用 Java7之前版本中,File类即代表了路径对象也封装

随机访问文件RandomAccessFile 与 内存映射文件MappedByteBuffer

一.RandomAccessFile RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必相同:但是其大小和位置必须是可知的.但是该类仅限于操作文件. RandomAccessFile不属于InputStream和OutputStream类系的.实际上,除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类系

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

原文:C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). 内存映射文件对于托管世界的开发人员来说似乎很陌生,但它确实已经是很远古的技术了,而且在操作系统中地位相当.实际上,任何想要共享数据的通信模型都会在幕后使用它. 内存映射文件究竟是个什么?内存映射文件允许你保留一块地址空间,然后将该物理存储映射到这块内存空间中进行操作.物理存储是文件管理,而内存

计算机程序的思维逻辑 (61) - 内存映射文件及其应用 - 实现一个简单的消息队列

本节介绍内存映射文件,内存映射文件不是Java引入的概念,而是操作系统提供的一种功能,大部分操作系统都支持. 我们先来介绍内存映射文件的基本概念,它是什么,能解决什么问题,然后我们介绍如何在Java中使用,我们会设计和实现一个简单的.持久化的.跨程序的消息队列来演示内存映射文件的应用. 基本概念 所谓内存映射文件,就是将文件映射到内存,文件对应于内存中的一个字节数组,对文件的操作变为对这个字节数组的操作,而字节数组的操作直接映射到文件上.这种映射可以是映射文件全部区域,也可以是只映射一部分区域.

【JavaNIO的深入研究4】内存映射文件I/O

内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件.有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问.这种解决办法能大大简化修改文件的代码.fileChannel.map(FileChannel.MapMode mode, long position, long size)将此通道的文件区域直接映射到内存中.注意,你必须指明,它是从文件的哪个位置开始映射的,映射的范围又有多大:也就是说,它还可以映射一个大文件的某个小片断. MappedByteB

java 内存映射文件

内存映射文件提供了Java有可能达到的最快IO操作,故高性能Java应用应使用“内存映射文件”来持久化数据,尤其是对于较大文件来说它确实比I/O流要快很多,但是小文件却未必. 内存映射文件可以加载大文件,文件的size上限取决于操作系统(内存的可寻址范围):32位,不能超过4GB,即2^32比特:64位,你几乎可以将任何文件映射到内存中并直接使用Java访问. 内存映射文件允许你使用direct或者non-direct 字节缓存(Byte buffer)来直接读写内存. 内存映射文件的一个关键优

NET 4 中 内存映射文件

原文链接 : http://blogs.msdn.com/salvapatuel/archive/2009/06/08/working-with-memory-mapped-files-in-net-4.aspx 预备知识 : 本文需要你对 OS 内存管理有一定了解. 我想探索下即将到来的 .NET 4 中一些与众不同的新特性,而不是已被大众所熟知的动态类型.协变与逆变等特性.出于对性能增强的喜爱,接下来俺将发表几篇新特性的博文. 内存映射文件对于托管世界的开发人员来说,似乎就像是火星人一样陌生

C#内存映射文件学习[转]

原文链接 内存映射文件是由一个文件到进程地址空间的映射. C#提供了允许应用程序把文件映射到一个进程的函(MemoryMappedFile.CreateOrOpen).内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对该文件进行操作之前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存.由此可以看出,使用内存映射文件处理存储于磁盘上的文件时,将不必再

MemoryMappedFile 内存映射文件 msdn

http://msdn.microsoft.com/zh-cn/library/dd997372%28v=vs.110%29.aspx 内存映射文件 .NET Framework 4.5 其他版本 1(共 1)对本文的评价是有帮助 - 评价此主题 内存映射文件包含虚拟内存中文件的内容. 利用文件与内存空间之间的映射,应用程序(包括多个进程)可以通过直接在内存中进行读写来修改文件. Managing Memory-Mapped Files in Win32 in the MSDN Library.