java nio 内存映射文件

 内存映射文件

一、内存映射文件

   内存映射文件的优势是比其他操作文件的方法访问文件的速度要快。

方法:

1)获得一个通道

FileChannel channel = FileChannel.open(path,options);

   还能通过在一个打开的 File 对象(RandomAccessFile、FileInputStream 或 FileOutputStream)上调用 getChannel() 方法获取。调用 getChannel() 方法会返回一个连接到相同文件的 FileChannel 对象且该 FileChannel 对象具有与 File 对象相同的访问权限。


2)调用FileChannel类的map方法从这个通道中获得一个ByteBuffer缓冲区,并且可以指定缓冲区的模式

调用 MappedByteBuffer map (FileChannel.MapMode mode, long position, long size);

position :起始位置

size:大小

mode的取值:

FileChannel.MapMode.READ_ONLY   只读缓冲区

FileChannel.MapMode.READ_WRITE   文件可写,但是不同步

FileChannel.MapMode.PRIVATE    缓冲区是可以修改的,但是不能将修改后的内容写到文件中

二、缓冲区数据结构

1)一个容量,缓冲区的容量是不变的

2)一个读写位置,下一个要进行操作的位置

3)缓冲区中有一个存储界限,这是数据的边界

4)一个可选标记,用于重复操作


0 <= 标记 <= 位置 <= 界限 <= 容量

缓冲区模型

对缓冲区的操作可以查看Java API java.nio.Buffer

三、文件加锁机制

当多个线程访问同一个文件的时候有可能造成文件数据的破坏,为了避免这种情况的发生,特定用一个锁来控制文件的访问

FileLock lock = channel.lock();     //锁定

FileLock lock = channel.tryLock();   //申请获得锁

lock.release();   //释放锁

还可以通过传参锁定缓冲区的一部分:

FileLock lock(long start, long size, boolean shared) 或 FileLock tryLock(long start, long size, boolean shared)

注意点:

  1、文件加锁机制是依赖于操作系统的

  2、意外的建议锁:在某些系统中文件锁仅仅是建议性的,可能出现一个应用未能得到锁,它仍旧可以向被另一个进程并发锁定的文件执行写操作;

  3、意外的原子性:在某些系统中,不能在锁定一个文件的同时将其映射到内存中,原子性;

  4、意外的全释放:在某些系统中,关闭一个通道会释放由JVM持有的底层文件上的所有锁,因此避免在同一个锁定文件上使用多个通道,不然其他通道的锁也可能被释放!

  5、不可重入锁:文件锁是由整个JVM持有的,两个由同一VM启动的程序不可能获得在同一个文件上的锁,如果尝试对VM上已加锁的文件再加锁,将抛出OverlappingFileLockException;

    (注意:多线程的ReentranLock是可重入的!简称可重入锁,而文件锁是不可重入锁)

  6、在网络文件系统上锁定文件是高度依赖于系统的,尽量避免使用文件锁






猜你喜欢

转载自blog.csdn.net/qq_32270067/article/details/78434843