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

标签: Java NIO
3人阅读 评论(0) 收藏 举报

文件通道(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中截图。








查看评论

NIO系列(二)——Channel通道复制和Selector选择器

Channel通道 NIO通过通道来读写数据 Channel有以下实现类 FileChannel:文件读写通道。 DatagramChannel:通过UDP读写网络中的数据。 SocketChanne...
  • luo4105
  • luo4105
  • 2017年06月23日 17:01
  • 604

Java NIO通道Channel的原理与获取

通道Channel:由java.nio.channels包定义。Channel表示IO源与目标打开的连接。Channel类似于传统的"流",只不过Channel本身不能直接访问数据,Channel只能...
  • u013063153
  • u013063153
  • 2017年07月31日 23:53
  • 1501

深入java NIO系列之通道分析与源码解读(二)

通道可以是单向的也可以是双向的,一个通道类可以实现ReadableByteChannel接口的read()方法,也可以实现WriteableByteChannel接口的write()方法,只要实现其中...
  • miliermili
  • miliermili
  • 2014年03月14日 12:34
  • 3010

通道和文件通道

通道是什么 通道式(Channel)是java.nio的第二个主要创新。通道既不是一个扩展也不是一项增强,而是全新的、极好的Java I/O示例,提供与I/O服务的直接连接。Channel用于在字节...
  • zhangyuan19880606
  • zhangyuan19880606
  • 2016年04月15日 15:45
  • 682

java nio为什么是通道(三):文件通道

前面已经提过,FileChannel对象不能直接创建,而是在一个打开的file对象(RandomAccessFile,FileInputStream或者FileOutputStream)上调用getC...
  • jiangfullll
  • jiangfullll
  • 2014年01月07日 00:40
  • 896

FileChannel通道 NIO 读写

package com.lanou.day21.test; import java.io.FileInputStream; import java.io.FileOutputStream; impo...
  • Lanou_XuWeiJie
  • Lanou_XuWeiJie
  • 2017年08月15日 15:50
  • 79

四通道和三通道的处理

#include #include #include using namespace std; using namespace cv; int main() { Mat rgba( 4, 4, ...
  • liyuqian199695
  • liyuqian199695
  • 2016年03月08日 22:16
  • 798

Java NIO笔记(六):内存映射文件及文件通道到通道批量传输数据

一、什么是内存映射文件
  • abc_key
  • abc_key
  • 2014年06月20日 02:13
  • 4938

Java NIO系列4:通道和选择器

前言今天加班回来,终于有时间继续更新NIO的文章了。在前一篇文章我们讲解了缓冲区的知识,并通过代码演示了如何使用缓冲区的API完成一些操作。这里要讲的通道于缓冲区关系密切,简单来说,缓冲区是填充数据的...
  • u011116672
  • u011116672
  • 2016年05月28日 23:21
  • 9969

javaNIO之通道的简单实现

今天再次看一遍NIO的通道。好好梳理下思路 我以最简单Demo为例,简单说明NIO的使用方式。不探讨具体的细节,因为一次性吸收这么多知识确实有些吃力。 简单的Demo需要你掌握这些内容: 1、开...
  • y492235584
  • y492235584
  • 2016年06月07日 10:54
  • 594
    个人资料
    等级:
    访问量: 8
    积分: 40
    排名: 187万+
    文章分类
    文章存档