甲乙小朋友的房子

甲乙小朋友很笨,但甲乙小朋友不会放弃

0%

内存映射文件

内存映射文件:利用虚拟内存实现将文件“映射”到内存中。文件对应于内存中的一个字节数组,对文件的操作变为对这个字节数组的操作,而字节数组的操作直接映射到文件上。这样这个文件就可以当做是一个内存数组一样的访问,这比传统的文件操作要快得多。

映射:硬盘上文件的位置与进程逻辑地址空间中一块大小相同的区域之间的一一对应

不过,这种映射是操作系统提供的一种假象,文件一般不会马上加载到内存,操作系统只是记录下了这回事,当实际发生读写时,才会按需加载。

这种按需加载的方式,使得内存映射文件可以方便处理非常大的文件,内存放不下整个文件也不要紧,操作系统会自动进行处理,将需要的内容读到内存,将修改的内容保存到硬盘,将不再使用的内存释放。

内存映射文件也有局限性,比如,它不太适合处理小文件,它是按页分配内存的,对于小文件,会浪费空间,另外,映射文件要消耗一定的操作系统资源,初始化比较慢。

java使用内存映射

步骤

  • 引入java.nio包

  • 从文件中获得一个通道(channel)。

    1
    FileChannel channel = FileChanne.open(path,options)

  • 通过调用FileChannel类的map方法从这个通道中获得一个ByteBuffer,它代表内存中的字节数组。其中,映射文件区域与映射模式支持三种方式: -- FileChannel.MapMode.READ_ONLY:缓冲区只读 -- FileChannel.MapMode.READ_WRITE:可读写。任何缓冲区的修改都会写回文件(非立即) -- FileChannel.MapMode.PRIVATE:缓冲区可写,但修改不会传播到文件中

映射完成后,文件就可以关闭了,后续对文件的读写可以通过MappedByteBuffer。

例:以读写模式映射文件"abc.dat",代码可以为:

1
2
3
4
5
6
7
8
9
RandomAccessFile file = new RandomAccessFile("abc.dat","rw");
try {
MappedByteBuffer buf = file.getChannel().map(MapMode.READ_WRITE, 0, file.length());
//使用buf...
} catch (IOException e) {
e.printStackTrace();
}finally{
file.close();
}

## 

参考文献

1.计算机程序的思维逻辑 (61) - 内存映射文件及其应用 - 实现一个简单的消息队列 2.java流的性能优化2-内存映射文件