MappedByteBuffer--FileChannel--RandomAccessFile

内存映射文件

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


MappedByteBuffer是ByteBuffer的子类,所以它具有了 ByteBuffer的全部方法,但新添了force()将缓冲区的内容强制刷新到存储设备中去、load()将存储设备中的数据加载到内存中、 isLoaded()位置内存中的数据是否与存储设置上同步。这里只简单地演示了一下put()和get()方法,除此以外,你还可使用 asCharBuffer( )之类的方法获得相应基本类型数据的缓冲视图后,能够方便的读写基本类型数据。
数组

import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;app

public class LargeMappedFiles {
 static int length = 0x8000000; // 128 Mbdom

 public static void main(String[] args) throws Exception {
  // 为了以可读可写的方式打开文件,这里使用RandomAccessFile来建立文件。
  FileChannel fc = new RandomAccessFile("test.dat", "rw").getChannel();
  // 注意,文件通道的可读可写要创建在文件流自己可读写的基础之上
  MappedByteBuffer out = fc
    .map(FileChannel.MapMode.READ_WRITE, 0, length);
  // 写128M的内容
  for (int i = 0; i < length; i++) {
   out.put((byte) 'x');
  }
  System.out.println("Finished writing");
  // 读取文件中间6个字节内容
  for (int i = length / 2; i < length / 2 + 6; i++) {
   System.out.print((char) out.get(i));
  }
  fc.close();
 }
}性能

Finished writing
xxxxxxspa

尽管映射写彷佛要用到FileOutputStream,可是映射文件中的全部输出 必须使用RandomAccessFile,但若是只须要读时可使用FileInputStream,写映射文件时必定要使用随机访问文件,可能写时要读的缘由吧。操作系统

 

该程序建立了一个128Mb的文件,若是一次性读到内存可能致使内存溢出,但这里访问好像只是一瞬间的事,这是由于,真正调入内存的只是其中的一小部分,其他部分则被放在交换文件上。这样你就能够很方便地修改超大型的文件了(最大能够到2 GB)。注意,Java是调用操做系统的"文件映射机制"来提高性能的。内存

本站公众号
   欢迎关注本站公众号,获取更多信息