内存映射文件
内存映射文件包含虚拟内存中文件的内容。 利用文件与内存空间之间的映射,应用程序(包括多个进程)可以通过直接在内存中进行读写来修改文件。
在java中java.nio包使得内存映射文件的操作变得十分简单。内存映射文件详情
常见做法:
- 首先从文件中获得一个channel ( 用于磁盘文件的一种抽象,他使得我们可以访问诸如内存映射、文件加锁机制以及文件间快速数据传递等操作系统特性。 )
FileChannel channel = FileChannel.open(path,options);
- 然后通过调用FileChannel类的map方法从这个通道中获得一个ByteBuffer。映射的文件区域与映射模式支持的有三种:
- FileChannel.MapMode.READ_ONLY : 所产生的缓冲区是只读的,任何对该缓冲区的写入尝试都会导致ReadOnlyBufferException异常。
- FileChannel.MapModel.READ_WRITE : 所产生的缓冲区是可写的,任何修改都会在某个时刻写回到文件中。注意,其他映射到同一个文件的程序可能不能立即看到这些修改,多个程序同时进行文件映射的确切行为是依赖于操作系统的。
- FileChannel.MapMode.PRIVATE : 所产生的缓冲区是可写的,但是任何修改对这个缓冲区来说都是私有的,不会传播到文件中。
java对于二进制数据使用高位在前的排序机制,但是如果需要以低位在前的排序方式处理包含二进制数字的文件,那么只需调用
buffer.order(ByteOrder.LITTLE_ENDIAN);
要查询缓冲区内当前的字节顺序可以调用:ByteOrder b = buffer.order()
下面是一个文件copy使用内存映射的例子:
常用的API:package com.example.byteBuffer; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; /** * Created by mirsery on 02/05/2017. */ public class MaoMemberBuffer { /**内存映射*/ public static void main(String[] args){ try { FileInputStream fileInputStream = new FileInputStream("test.mp4"); FileOutputStream fileOutputStream = new FileOutputStream("test1.mp4"); FileChannel fileInChannel = fileInputStream.getChannel(); FileChannel fileOutChannel = fileOutputStream.getChannel(); MappedByteBuffer mappedByteBuffer = fileInChannel.map(FileChannel.MapMode.READ_ONLY,0,fileInChannel.size()); fileOutChannel.write(mappedByteBuffer); mappedByteBuffer.flip();//指针指向0 fileOutChannel.close(); fileOutputStream.close(); fileInChannel.close(); fileInputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
- java.nio.channels.FileChannel
- static FileChannel open(Path path,OpenOption … optioins)
打开指定路径的文件通道,默认状况下,通道打开时用于读入。 - MappedByteBuffer map(FileChannel.MapMode mode,long position,long size)
将文件的一个区域映射到内存中 - boolean hasRemining()
如果当前的缓冲区位置没有到达这个缓冲区的界限位置,则返回true。 - int limit()
返回这个缓冲区的界限位置,即没有任何价值可用的第一个位置。
- static FileChannel open(Path path,OpenOption … optioins)