内存映射文件-java读取超大文件
2011-04-08 16:18
351 查看
新的FileChannel类提供了一个名为map( )的方法,该方法可以在一个打开的文件和一个特殊类型的ByteBuffer之间建立一个虚拟内存映射(第一章中已经归纳了什么是内存映射文件以及它们如何同虚拟内存交互)。在FileChannel上调用map( )方法会创建一个由磁盘文件支持的虚拟内存映射(virtual memory mapping)并在那块虚拟内存空间外部封装一个MappedByteBuffer对象。
由map( )方法返回的MappedByteBuffer对象的行为在多数方面类似一个基于内存的缓冲区,只不过该对象的数据元素存储在磁盘上的一个文件中。调用get( )方法会从磁盘文件中获取数据,此数据反映该文件的当前内容,即使在映射建立之后文件已经被一个外部进程做了修改。通过文件映射看到的数据同您用常规方法读取文件看到的内容是完全一样的。相似地,对映射的缓冲区实现一个put( )会更新磁盘上的那个文件(假设对该文件您有写的权限),并且您做的修改对于该文件的其他阅读者也是可见的。
通过内存映射机制来访问一个文件会比使用常规方法读写高效得多,甚至比使用通道的效率都高。因为不需要做明确的系统调用,那会很消耗时间。更重要的是,操作系统的虚拟内存可以自动缓存内存页(memory page)。这些页是用系统内存来缓存的,所以不会消耗Java虚拟机内存堆(memory heap)。
一旦一个内存页已经生效(从磁盘上缓存进来),它就能以完全的硬件速度再次被访问而不需要再次调用系统命令来获取数据。那些包含索引以及其他需频繁引用或更新的内容的巨大而结构化文件能因内存映射机制受益非常多。如果同时结合文件锁定来保护关键区域和控制事务原子性,那您将能了解到内存映射缓冲区如何可以被很好地利用。
下面让我们来看一下如何使用内存映射:
可以看到,只有一种map( )方法来创建一个文件映射。它的参数有mode,position和size。参数position和size同lock( )方法的这两个参数是一样的(在前面的章节中已有讨论)。我们可以创建一个MappedByteBuffer来代表一个文件中字节的某个子范围。例如,要映射100到299(包含299)位置的字节,可以使用下面的代码:
MappedByteBuffer buffer = fileChannel.map (FileChannel.MapMode.READ_ONLY, 100, 200);
如果要映射整个文件则使用:
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
由map( )方法返回的MappedByteBuffer对象的行为在多数方面类似一个基于内存的缓冲区,只不过该对象的数据元素存储在磁盘上的一个文件中。调用get( )方法会从磁盘文件中获取数据,此数据反映该文件的当前内容,即使在映射建立之后文件已经被一个外部进程做了修改。通过文件映射看到的数据同您用常规方法读取文件看到的内容是完全一样的。相似地,对映射的缓冲区实现一个put( )会更新磁盘上的那个文件(假设对该文件您有写的权限),并且您做的修改对于该文件的其他阅读者也是可见的。
通过内存映射机制来访问一个文件会比使用常规方法读写高效得多,甚至比使用通道的效率都高。因为不需要做明确的系统调用,那会很消耗时间。更重要的是,操作系统的虚拟内存可以自动缓存内存页(memory page)。这些页是用系统内存来缓存的,所以不会消耗Java虚拟机内存堆(memory heap)。
一旦一个内存页已经生效(从磁盘上缓存进来),它就能以完全的硬件速度再次被访问而不需要再次调用系统命令来获取数据。那些包含索引以及其他需频繁引用或更新的内容的巨大而结构化文件能因内存映射机制受益非常多。如果同时结合文件锁定来保护关键区域和控制事务原子性,那您将能了解到内存映射缓冲区如何可以被很好地利用。
下面让我们来看一下如何使用内存映射:
public abstract class FileChannel extends AbstractChannel implements ByteChannel, GatheringByteChannel, ScatteringByteChannel { public abstract MappedByteBuffer map (MapMode mode, long position,long size) public static class MapMode { public static final MapMode READ_ONLY public static final MapMode READ_WRITE public static final MapMode PRIVATE } }
可以看到,只有一种map( )方法来创建一个文件映射。它的参数有mode,position和size。参数position和size同lock( )方法的这两个参数是一样的(在前面的章节中已有讨论)。我们可以创建一个MappedByteBuffer来代表一个文件中字节的某个子范围。例如,要映射100到299(包含299)位置的字节,可以使用下面的代码:
MappedByteBuffer buffer = fileChannel.map (FileChannel.MapMode.READ_ONLY, 100, 200);
如果要映射整个文件则使用:
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
相关文章推荐
- java读取大文件 超大文件的几种方法
- java频繁读取文件导致,内存不断增加
- Java NIO 按行读取超大文件
- 解决java读取大文件内存溢出问题、如何在不重复读取与不耗尽内存的情况下处理大文件
- java 读取文件——按照行取出(使用BufferedReader和一次将数据保存到内存两种实现方式)
- 解决java读取大文件内存溢出问题、如何在不重复读取与不耗尽内存的情况下处理大文件
- JAVA读取XML文件放在内存中,如果XML文件发生变化时,重新读取XML文件,并覆盖内存中的数据
- Java-NIO(五):通道(Channel)的数据传输与内存映射文件
- java中利用RandomAccessFile读取超大文件
- c语言实现mmap内存映射读取文件和文件加密
- java_croe 学习笔记之新IO---java.nio 之内存映射文件
- 用C语言读取大文件的问题 内存映射
- Java-NIO(五):通道(Channel)的数据传输与内存映射文件
- java读取文件到内存
- iOS将大文件映射到内存(读取大文件)
- JAVA中的内存映射文件
- Java的随机读写文件-RandomAccessFile 与内存映射
- java读取超大文件
- java大文件读写操作,java nio 之MappedByteBuffer,高效文件/内存映射
- java nio 映射文件内容到内存