(四)nio通道之文件通道(FileChannel)

文件通道(File Channel)总是阻塞式的,因此不能被置于阻塞模式。

一、FileChannel类的概述:

FileChannel对象不能直接创建。一个FileChannel实例只能通过在一个打开的file对象(RandomAccessFile、FileInputStream或 FileOutputStream)上调用getChannel( )方法获取。调用getChannel( )方法会返回一个连接到相同文件的FileChannel对象且该FileChannel对象具有与file对象相同的访问权限,然后就可以使用该通道对象来利用强大的FileChannel API了。

FileChannel 对象是线程安全的。多个进程可以在同一个实例上并发调用方法而不会引起任何问题,不过并非所有的操作都是多线程的。影响通道位置或者影响文件大小的操作都是单线程的。如果有一个线程已经在执行会影响通道位置或文件大小的操作,那么其他尝试进行此类操作之一的线程必须等待。并发行为也会受到底层的操作系统或文件系统影响。

FileChannel 类保证同一个 Java 虚拟机上的所有实例看到的某个文件的视图均是一致的,但是 Java虚拟机却不能对超出它控制范围的因素提供担保。通过一个 FileChannel 实例看到的某个文件的视图同通过一个外部的非 Java 进程看到的该文件的视图可能一致,也可能不一致。多个进程发起的并发文件访问的语义高度取决于底层的操作系统和(或)文件系统。一般而言,由运行在不同 Java虚拟机上的 FileChannel 对象发起的对某个文件的并发访问和由非 Java 进程发起的对该文件的并发访问是一致的。



FileChannel常见的API:

public abstract long position( )
public abstract void position (long newPosition)
public abstract int read (ByteBuffer dst)
public abstract int read (ByteBuffer dst, long position)
public abstract int write (ByteBuffer src)
public abstract int write (ByteBuffer src, long position)
public abstract long size( )
public abstract void truncate (long size)

public abstract void force (boolean metaData)

二、文件锁定:

在集成许多其他非 Java 程序时,文件锁定显得尤其重要。文件锁定特性在很大程度上依赖本地的操作系统实现。并非所有的操作系统和文件系统都支持共享文件锁。对于那些不支持的,对一个共享锁的请求会被自动提升为对独占锁的请求。这可以保证准确性却可能严重影响性能。

另外,并非所有平台都以同一个方式来实现基本的文件锁定。在不同的操作系统上,甚至在同一个操作系统的不同文件系统上,文件锁定的语义都会有所差异。一些操作系统仅提供劝告锁定,一些仅提供独占锁,而有些操作系统可能两种锁都提供。您应该总是按照劝告锁的假定来管理文件锁,因为这是最安全的。

如果一个线程在某个文件上获得了一个独占锁,然后第二个线程利用一个单独打开的通道来请求该文件的独占锁,那么第二个线程的请求会被批准。但如果这两个线程运行在不同的 Java 虚拟机上,那么第二个线程会阻塞,因为锁最终是由操作系统或文件系统来判优的并且几乎总是在进程级而非线程级上判优。锁都是与一个文件关联的,而不是与单个的文件句柄或通道关联。

要获得一个共享锁,必须先以只读权限打开文件,而请求独占锁时则需要写权限。锁定区域的范围不一定要限制在文件的 size 值以内,锁可以扩展从而超出文件尾。因此,可以提前把待写入数据的区域锁定,也可以锁定一个不包含任何文件内容的区域,比如文件最后一个字节以外的区域。如果之后文件增长到达那块区域,那么文件锁就可以保护该区域的文件内容了。相反地,如果锁定了文件的某一块区域,然后文件增长超出了那块区域,那么新增加的文件内容将不会受到文件锁的保护。

不带参数的简单形式的 lock( )方法是一种在整个文件上请求独占锁的便捷方法,锁定区域等于它能达到的最大范围。该方法等价于:fileChannel.lock (0L, Long.MAX_VALUE, false); 如果正请求的锁定范围是有效的,那么 lock( )方法会阻塞,它必须等待前面的锁被释放。

三、FileChannel操作文件的代码示例已经在http://blog.csdn.net/jun3518/article/details/79929235中截图。








阅读更多
文章标签: Java NIO
上一篇(三)nio通道之Channel的类型、通道的创建和通道的Scatter(分散)和Gather(聚集)
下一篇Struts2-使Struts2能运行起来的的简单配置
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭