内存映射文件

    FileChannel类提供了一个名为map的方法,将一个打开的文件和一个特殊类型的ByteBuffer之间建立一个虚拟内存映射。

    由map()方法返回的MappredByteBuffer对象的行为在多数方面类似一个基于内存的缓冲区,只不过该对象的数据元素存储在磁盘上的一个文件。调用get()方法会从磁盘文件中获取数据,此数据反映该文件的当前内容。

 

public abstract class FileChannel  
extends AbstractChannel  
implements ByteChannel, GatheringByteChannel, ScatteringByteChannel 
{ 
    // This is a partial API listing 
    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 
    } 
}

   与文件锁的范围机制不一样,映射文件的范围不应超过文件的实际大小。如果您请求一个超出文件大小的映射,文件会被增大以匹配映射的大小

   同常规的文件句柄类似,文件映射可以是可写的或只读的。MapMode.READ_ONLY和MapMode.READ_WRITE 意义是很明显的,它们表示您希望获取的映射只读还是允许修改映射的文件。请求的映射模式将受被调用map( )方法的FileChannel 对象的访问权限所限制。MapMode.PRIVATE 表示您想要一个写时拷贝(copy -on-write)的映射。味着通过put( )方法所做的任何修改都会导致产生一个私有的数据拷贝并且该拷贝中的数据只有MappedByteBuffer实例可以看到。该过程不会对底层文件做任何修改,而且一旦缓冲区被施以垃圾收集动作(garbage collected),那些修改都会丢失。使用MapMode.PRIVATE模式并不会导致您的缓冲区看不到通过其他方式对文件所做的修改。对文件某个区域的修改在使用MapMode.PRIVATE模式的缓冲区中都能反映出来,除非该缓冲区已经修改了文件上的同一个区域。

   内存和文件系统都被划分成了页。当在一个写时拷贝的缓冲区上调用put( )方法时,受影响的页会被拷贝,然后更改就会应用到该拷贝中。

    有unmap( )方法:一个映射一旦建立之后将保持有效,直到MappedByteBuffer对象被施以垃圾收集动作为止。关闭相关联的FileChannel不会破坏映射,只有丢弃缓冲区对象本身才会破坏该映射。

     MappedByteBuffer对象都是直接的,这意味着它们占用的内存空间位于Java虚拟机内存堆之外。为MappedByteBuffers也是ByteBuffers,所以能够被传递SocketChannel之类通道的read( )或write( )以有效传输数据给被映射的文件或从被映射的文件读取数据。

public abstract class MappedByteBuffer extends ByteBuffer 
{ 
    // This is a partial API listing 
    public final MappedByteBuffer load( ) 
    public final boolean isLoaded( ) 
    public final MappedByteBuffer force( ) 
}
    为一个文件建立虚拟内存映射之后,文件数据通常不会因此被从磁盘读取到内存。该过程类似打开一个文件:文件先被定位,然后一个文件句柄会被创建,当您准
备好之后就可以通过这个句柄来访问文件数据。

public abstract class MappedByteBuffer extends ByteBuffer 
{ 
    // This is a partial API listing 
    public final MappedByteBuffer load( ) 
    public final boolean isLoaded( ) 
    public final MappedByteBuffer force( ) 
}

    load( )方法会加载整个文件以使它常驻内存,在一个映射缓冲区上调用load( )方法会是一个代价高的操作,因为它会导致大量的页调入(page-in),具体数量取决于文件中被映射区域的实际大小。然而,load( )方法返回并不能保证文件就会完全常驻内存,这是由于请求页面调入(demand paging)是动态的。

   用isLoaded( )方法来判断一个被映射的文件是否完全常驻内存了。

   force( )同FileChannel类中的同名方法相似,该方法会强制将映射缓冲区上的更改应用到永久磁盘存储器上。当用MappedByteBuffer对象来更新一个文件,您应该总是使用MappedByteBuffer.force( )而非FileChannel.force( ),因为通道对象可能不清楚通过映射缓冲区做出的文件的全部更改。

   如果映射是以MapMode.READ_ONLY或MAP_MODE.PRIVATE模式建立的,那么调用force( )方法将不起任何作用,因为永远不会有更改需要应用到磁盘上。

public abstract class FileChannel extends AbstractChannel 
implements ByteChannel, GatheringByteChannel, ScatteringByteChannel 
{ 
    // This is a partial API listing 
    public abstract long transferTo (long position, long count, WritableByteChannel target) 
    public abstract long transferFrom (ReadableByteChannel src, long position, long count) 
}
    transferTo( )和transferFrom( )方法允许将一个通道交叉连接到另一个通道,而不需要通过一个中间缓冲区来传递数据。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值