NIO-FileChannel详解

13 篇文章 0 订阅

一.FileLock(通道文件锁,记录区域锁):表示文件区域锁定标记.FileLock并没有实现lock接口,它仅仅是一个辅助锁操作类.每次通过FileChannel.lock()或者tryLock()获取文件锁.一旦获取锁,那么lock将持续有效,直到被release(),以及JVM退出.可以通过对fileLock.isValid()检测锁的有效性.

文件锁要么是独占的,有么是共享的.共享锁可以阻止并发运行的程序获取独占锁,但是允许程序继续获取共享锁.独占锁阻止其他获取任意类型锁.可以通过isShared()检测锁的模式.某些平台不支持文件共享锁,则共享锁请求被升级为独占锁,此后操作将以独占锁执行.

单个JVM在某个特定文件上所保持的锁是不重叠的(即在进程级别不会重复获取锁).要测试某个候选锁定范围是否与现有的锁定重叠,可以使用overlaps方法.

文件锁和通道(file)关联.文件锁是以JVM进程为单位保持(OS特性).它们不适应于控制同一个JVM内多个线程对文件的访问.(多线程下对文件访问),但是fileLock对象可以在多线程环境中安全使用.

FileLock最终直接映射为底层操作系统的"文件锁",FileLock的特性将受制于OS;因为任何进程都可以透明的获得文件锁的情况.在某些平台上,某个通道释放锁,会导致JVM进程释放底层文件的所有锁定,不管该锁是否为该通道获取的.因为我们为了避免这些因平台不同而带来的潜在问题,建议一个JVM进程中,对特定文件,FileChannel应该被唯一化.

  • protected FileLock(FileChannel channel,long position,long size,boolean shared):初始化一个fileLock,并制定锁关联的channel,以及需要锁定的文件区域,锁的模式.FileLock不能直接被实例化,在API级别,可以在FileChannel.lock(...)获得需要的文件锁.每个FileLock实例都会持有position,size,shared属性,而且将不能再被改变.
  • public final FileChannel channel():返回当前lock锁关联度FileChannel.
  • public final boolean overlaps(long position,long size):判断此锁定区域是否与制定的区域重叠,只要当前lock覆盖至少一个直接时返回true.
  • public abstract boolean isValid():检测此锁是否有效,此值有底层控制,FileLockImpl.当锁获取成功时,此值为true.如果锁被release或者fileChannle被关闭,将返回false.
  • public abstract void release():释放锁.如果此时fileChannel已经关闭,则抛出ClosedChannelException.此后将间接调用fileChannel.release(fileLock)来释放锁.因此可见,锁的获取和释放,均和关联的channel有关.需要声明的是,FileLock仅仅是一个API级别的锁状态表示,他持有锁的一些信息,但FileLock本身无法改变锁的状态,只能间接的通过FileChannel来操作.


 
二.FileChannel(文件通道类):此类为抽象类,底层有FileChannelImpl支持.


源代码参考:http://javasourcecode.org/html/open-source/jdk/jdk-6u23/sun/nio/ch/FileChannelImpl.html

FileChannel实现了InterrutableChannel/GatheringByteChannel/ScatteringByteChannel,它并没有向其他Socket通讯通道实现SelectableChannel.

FileChannel用于读取/写入/Mapping文件的通道.

  1. 以不影响通道当前位置的方式,对文件中绝对位置的字节进行读取或者写入.
  2. 将文件中的某个区域直接Mapping到内存中,对于较大的文件,这通常比调用普通的read或者write方法更加有效.
  3. 强制(force)对底层存储设备进行文件的更新,确保在系统崩溃时不丢失数据.
  4. 以一种可被操作系统优化为直接向文件缓存发送或者从中读取的高速传递方法,将字节从文件传输到某个其他通道.
  5. 可以lock指定的文件区域,以防止其他程序进行访问.

多个并发线程可安全地使用文件通道。可随时调用关闭方法,正如 Channel 接口中所指定的。对于涉及通道位置或者可以更改其文件大小的操作,在任意给定时间只能进行一个这样的操作;如果尝试在第一个操作仍在进行时发起第二个操作,则会导致在第一个操作完成之前阻塞第二个操作。

可以并发处理其他操作,特别是那些采用显式位置的操作;但是否并发处理则取决于基础实现,因此是未指定的。

 

此外我们可以在FileChannel中查看到2个方法:transferFrom和transferTo,用来实现“zero-copy”(socket sendfile特性),即允许将文件中的数据直接发送到socket中,或者从socket中直接读取数据进而写入File中。

通过FileInputStream.getChannel()获得的通道,只能read.通过FileOutputStream.getChannel()获取的通道,只能write.FileChannel,不能创建文件.RandomAccessFile在"r"模式下为只读,在"rw"模式下允许读写.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值