`
airu
  • 浏览: 267515 次
  • 性别: Icon_minigender_1
  • 来自: 云南
社区版块
存档分类
最新评论

JavaNIO-文件通道

 
阅读更多
文件通道,是一种特殊的通道。
对于文件通道来说,是不能阻塞的。所以并不能设置非阻塞模式。
对于异步文件I/O来说,这是很多操作系统支持的,NIO也会增强。

一个FileChannel只能从RandomAccessFile,FileInputStream和FileOutputStream来获取(getChannel),然后你就获得了某种能力,请看:
package java.nio.channels; public abstract class FileChannel extends 
AbstractChannel implements ByteChannel, GatheringByteChannel, ScatteringByteChannel { 
// This is a partial API listing
// All methods listed here can throw java.io.IOException 
public abstract int read (ByteBuffer dst, long position) 
public abstract int write (ByteBuffer src, long position) 
public abstract long size( )
public abstract long position( ) 
public abstract void position (long newPosition)
public abstract void truncate (long size) 
public abstract void force (boolean metaData) 
public final FileLock lock( )
public abstract FileLock lock (long position, long size, boolean shared) 
public final FileLock tryLock( ) 
public abstract FileLock tryLock (long position, long size, boolean shared) 
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 
	}
public abstract long transferTo (long position, long count, WritableByteChannel target) public abstract long transferFrom (ReadableByteChannel src, long position, long count)
}


以上的操作,都会抛出java.io.IOException
FileChannel对象是线程安全的,但是注意的是,影响到通道位置和文件大小的操作是单线程的。

对于同一个虚拟机,我们看到的对于某一个文件的FileChannel实例视图都是一致的。
FileChannel对于的操作和POSIX中的一些API函数很相像。
FileChannel
RandomAccessFilePOSIX system callread()read()read()\nwrite()write()write()\nsize()length()fstat()\nposition()getFilePointer()lseek()\nposition(long newPosition)seek()lseek()\ntruncate()setLength()ftruncate()\nforce()getFD().sync()fsync()\n


FileChannel里有一个position属性,表示下一个要读取的文件位置。这个和缓冲区有点像。但是可以超过这个值。如果write的position超过了文件大写,就会增大文件,有可能造成空洞文件。如果是read的话,到达文件尾,则是返回-1.
如果带有一个long参数的position则可以设置文件的位置大小,这是并不改变文件大小。只有当read或者write的时候,才真正的改变。

注意position是从底层描述符中得来的,被作为通道引用获去来源的文件共享对象,所以改变她,其他的对象可以看到。


trucate函数会把新的size以外的数据清除。如果size大于原来的size,那么position会被改变成新的size。


对于force函数,则是一个同步磁盘函数。把修改都应用到磁盘上。如果带有boolean型参数,那么表明是否要把元数据也同步。元数据是指,文件的所有者,访问权限,上次修改时间等信息。这要看具体的应用,因为同步这些信息会有额外的底层I/O操作。

文件锁。
文件锁针对的是文件,所以和通道无关。一般来说分为共享锁(shared)和独占锁(exclusive)。
注意,如果一个进程下的另一个线程访问一个加独占锁的文件,是可以的。因为这是底层操作系统的实现。只是针对不同的进程。
所以,也有可能在某些操作系统上,独占锁只是一个建议锁,非强制性的。
关于管道上的锁,有如下操作。

public abstract class FileChannel extends AbstractChannel implements ByteChannel, GatheringByteChannel, ScatteringByteChannel { 
// This is a partial API listing 
	public final FileLock lock( )
	public abstract FileLock lock (long position, long size, boolean shared) 
	public final FileLock tryLock( ) 
	public abstract FileLock tryLock (long position, long size, boolean shared) 
}

我们可以看到,lock可以锁住一个文件的某个区域。而且这个区域可以使比文件还大。
超出文件尾的。这样,新写入的内容也被锁住。使用lock可能会阻塞,等待前一个lock被释放。
tryLock和lock一样。只是如果当时没有可用锁,就立即返回一个null,而不是阻塞。
FileLock 类如下:
public abstract class FileLock {
	public final FileChannel channel( )
	public final long position( ) 
	public final long size( ) 
	public final boolean isShared( ) 
	public final boolean overlaps (long position, long size) 
	public abstract boolean isValid( ); 
	public abstract void release( ) throws IOException; 
}


一旦FileLock对象创建就生效。注意,创建以后,position,是否独占,大小就不能改变了。
FileLock是线程安全的,可以多个线程同时访问一个锁。注意,在你不确定操作系统是否支持独占性时,使用isShared()来判断是否该锁支持共享。
如果你要查看一个感兴趣的区域是否与当前的锁有冲突,可以使用 overlaps,这个函数返回的是当前进程上的,即使是返回为false,也不一定可以获取到FileLock。

最后,使用文件锁,一定要释放。使用try...catch...finally
FileLock lock = fileChannel.lock( )
 try { 
	<perform read/write/whatever on channel>
 } catch (IOException) 
	[ <handle unexpected exception> } 
finally {
	lock.release( )
}


注意,FileLock是针对不同进程的。如果在一个进程内,锁是无意义的。


                 
分享到:
评论

相关推荐

    Java视频教程 Java游戏服务器端开发 Netty NIO AIO Mina视频教程

    [第7节] Java NIO流-文件通道操作.flv [第8节] Java NIO流-选择器 .flv [第9节] Java NIO流-选择器操作.flv 四、Mina视频教程 00、Mina视频课程介绍.flv 01、Mina服务端helloWorld入门.flv 02、Mina客户端...

    nio-samples:Java NIO库使用示例

    相同的回显服务器,但使用NIO2异步通道。 创建10000个客户端连接的类,您可以在nio服务器上测试负载。 监视服务API的简单用法。 监视预定义目录中的更改的类。 您可以播放生成的jar文件。 请按照以下步骤操作: ...

    nio.rar_FastCopyFile.java_NIO_UseFloatBuffer.java_java nio_文件锁

    Java NIO 源码适合初学者,里面包括通道和Buffer的基本适用,以及文件锁,和内存文件映射等等

    Java NIO(通道+缓冲区+选择器)

    Java NIO通道:通道基础、文件通道、Socket通道、工具类 Java NIO缓冲区:基础、缓冲区(Buffer)、创建缓冲区、直接缓冲区(DirectByteBuffer) Java NIO选择器:核心概念、选择器使用、Demo、选择器深入、

    Java NIO异步文件通道原理及用法解析

    主要介绍了Java NIO异步文件通道原理及用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    javasnmp源码-nio-learn:JavaNIO使用示例,NIO的使用,TCP,UDP的简单示例

    NIO将以更加高效的方式进行文件的读写操作。 Java NIO与普通IO的主要区别 io nio 面向流 面向缓冲区(buffer,channel) 堵塞io 非堵塞io - 选择器 java nio主要的核心组件 缓冲区 buffer 通道 Channels 选择器 ...

    2021最新-Java NIO视频教程-视频教程网盘链接提取码下载 .txt

    教程内容涵盖:阻塞和非阻塞IO、Channel通道、Buffer缓冲区、Selector选择器、Pipe管道、FileLock文件锁,以及Path、Files、异步FileChannel和Charset字符编码等,并通过一个多人聊天室的综合案例,把所有的NIO知识...

    Java IO 体系.md

    Java IO 体系 - Java IO 体系 ...Java IO 是一个庞大的知识体系,很多人学着学着就会学懵了,包括我在内也是如此,所以本文将会从 Java 的 BIO 开始,一步一步深入学习,引出 JDK1.4 之后出现的 NIO

    Java NIO原理和使用

    Java NIO非堵塞应用通常适用用在I/O读写等方面,我们知道,系统运行的性能瓶颈通常在I/O读写,包括对端口和文件的操作上,过去,在打开一个I/O通道后,read()将一直等待在端口一边读取字节内容,如果没有内容进来,...

    mina:Java Nio Apache Mina Java Nio

    在以往的java的IO操作的过程中都是面向字节流操作,并且读写操作是单向的操作,而在java1.4添加nio包新的io不再像以前的标准的io操作一样面向流操作,而NIO是面向块的操作,并且有通道、缓冲区等重要的部分组成。...

    Java NIO 网络编程初探

    NIO同样拥有文件读写,网络通信等IO操作,今天我们来看看NIO中的TCP网络通信的使用方法。 2. Java NIO 三大核心 Java NIO 有三大核心要素:Channel、Buffer和Selector。Java IO 的操作都是基于输入输出流的,而NIO则...

    java jdk-api-1.6 中文 chmd

    java.nio.channels 定义了各种通道,这些通道表示到能够执行 I/O 操作的实体(如文件和套接字)的连接;定义了用于多路复用的、非阻塞 I/O 操作的选择器。 java.nio.channels.spi 用于 java.nio.channels 包的服务...

    详解JavaNIO

    所以,jdk1.4发布了NIO包,NIO的文件读写设计颠覆了传统IO的设计,采用『通道』+『缓存区』使得新式的IO操作直接面向缓存区,并且是非阻塞的,对于效率的提升真不是一点两点,我们一起来看看。我们说过,NIO的核心...

    尚硅谷Java视频_NIO 视频教程

    尚硅谷_NIO_通道的数据传输与内存映射文件 ·06. 尚硅谷_NIO_分散读取与聚集写入 ·07. 尚硅谷_NIO_字符集 Charset ·08. 尚硅谷_NIO_阻塞与非阻塞 ·09. 尚硅谷_NIO_阻塞式 ·10. 尚硅谷_NIO_非阻塞式 ·11. ...

    Java流NIO

    NIO于原来的IO有相同的功能,但是他们之间的使用方式是完全不同的,NIO是面向缓冲区,面向通道的的IO操作,NIO拥有更加高效的进行文件读写。 另外NIO在网络编程可以是一个无阻塞的IO交互,可以大大提升Socket交互的...

    Java NIO与IO的差别和比较

     NIO包(java.nio.*)引入了四个关键的抽象数据类型,它们共同解决传统的I/O类中的一些问题。  1. Buffer:它是包括数据且用于读写的线形表结构。当中还提供了一个特殊类用于内存映射文件的I/O操作。  2. ...

    nio:Clojure对java.nio的支持

    o Clojure对java.nio的支持。 将clojure.java.io的输入流,输出流和复制功能扩展到java.nio类。 定义新的强制功能缓冲区,字节缓冲区,字符缓冲区,双缓冲区,浮点缓冲区,整数缓冲区,长缓冲区,短缓冲区,通道,可...

    java实现的LSB顺序隐写

    2、使用java NIO读取被嵌入的文件,将其转换为byte数组,需要特别指出的是原生方法得到是byte类型的数组,但是算法实现需要更加精细的操作,所以还需要对得到的byte数组进行进一步的转换封装,将其转换成形如10101...

    Java性能优化之使用NIO提升性能(Buffer和Channel)

    在软件系统中,由于IO的速度要比内存慢...使用java.nio.charset.Charset作为字符集编码解码解决方案;增加通道(channel)对象,作为新的原始I/O抽象;支持锁和内存映射文件的文件访问接口;提供了基于Selector的异步网

Global site tag (gtag.js) - Google Analytics