文件通道,是一种特殊的通道。
对于文件通道来说,是不能阻塞的。所以并不能设置非阻塞模式。
对于异步文件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函数很相像。
FileChannelRandomAccessFile | POSIX 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 NIO(New IO)是Java 1.4版本引入的一个新模块,它提供了一种不同于传统IO(基于字节流和字符流)的I/O操作方式。传统的IO模型是阻塞式的,而NIO的核心特点是非阻塞,这使得在处理大量并发I/O请求时更为高效。...
在Java NIO中,数据是以通道(Channels)和缓冲区(Buffers)的形式进行传输,而不是直接通过流。这种设计使得NIO能够同时处理多个输入/输出操作,从而实现多路复用。 标题“nio.rar_NIO_NIO-socket_java nio_java ...
Java NIO(非阻塞I/O)编程是Java平台中的一种高效I/O处理方式,相比传统的BIO(阻塞I/O),NIO提供了更灵活、性能更高的数据传输机制。本书《Java NIO Programming Cookbook》旨在深入浅出地介绍如何利用Java NIO...
在NIO中,通道代表了一个打开的I/O流,它可以是文件、套接字或其他类型的流。通道是非阻塞的,意味着即使数据没有准备好,读取或写入操作也不会被阻塞,而是返回一个状态指示是否可以继续进行。这大大提高了服务器...
Java NIO-Channel-Socket通道-概述 - **主要内容**:介绍Socket通道的基础知识,包括SocketChannel和ServerSocketChannel。 - **学习目标**:理解Socket通道的基本概念和使用场景。 #### 8. Java NIO-Channel-...
在本篇文章中,我们将深入探讨Java NIO如何读取文件。 一、NIO的基本概念 1. 缓冲区(Buffer):NIO的核心组件,用于存储数据。Java提供了多种Buffer类,如ByteBuffer、CharBuffer、IntBuffer等,分别对应不同数据...
`获取文件通道。 - `MappedByteBuffer inputBuffer = channel.map(FileChannel.MapMode.READ_ONLY, f.length()*begin_fz/begin_fm, f.length()*end_fz/end_fm);`将文件的一部分映射到内存中。 3. **数据读取** - ...
总结,Java NIO提供了一套高效、灵活的文件写入机制,包括通道、缓冲区、内存映射文件和选择器等组件。了解并掌握这些特性,能帮助开发者编写出更高效的I/O程序,特别是对于处理大量并发I/O操作的场景。在实际编程中...
通道可以是文件通道、套接字通道等。 NIO 库也提供了许多实用的工具和类,例如 ByteBuffer、CharBuffer、IntBuffer 等,用于处理不同的数据类型。 Java NIO 库提供了一种新的、高效的 I/O 机制,可以满足不同的 I/...
Java NIO(New IO)是Java 1.4版本引入的一个新模块,它提供了一种新的方式来处理I/O操作,相比传统的IO流,NIO提供了更高效、更灵活的数据读写方式。在这个主题中,我们将深入探讨Java NIO如何用于写文件,特别是在...
[第7节] Java NIO流-文件通道操作.flv [第8节] Java NIO流-选择器 .flv [第9节] Java NIO流-选择器操作.flv 四、Mina视频教程 00、Mina视频课程介绍.flv 01、Mina服务端helloWorld入门.flv 02、Mina客户端...
Java NIO提供了一些常见的通道实现,如SocketChannel(用于网络通信)、FileChannel(用于文件操作)等。 3. **Buffer(缓冲区)**:在NIO中,数据读写都是通过缓冲区进行的。缓冲区是一个可以容纳特定类型数据(如...
Java NIO支持多种类型的通道,包括文件通道(FileChannel)、套接字通道(SocketChannel)和服务器套接字通道(ServerSocketChannel)等。通道可以同时进行读写操作,并且可以实现异步读写。 2. **缓冲区(Buffers...
4. **文件通道(File Channel)**:文件通道是直接与文件系统交互的通道,支持映射文件到内存(Memory-Mapped File)进行高速读写。 5. **网络通道(Network Channels)**:如SocketChannel和ServerSocketChannel,...
Java NIO提供了多种类型的通道,如FileChannel、SocketChannel、DatagramChannel等,分别对应于文件、TCP网络连接和UDP网络连接。 在课程中,第4节将详细讲解Java NIO的通道概念,特别是`Channel`接口及其主要实现...
本压缩包中的"java-instantcode-developing-applications-using-java-nio.17016.chm"文件很可能是详细讲解如何使用Java NIO进行应用开发的电子书或文档,涵盖了从基础概念到高级特性的全面内容,可以帮助开发者深入...
本项目“Large-File-Processing-master_javanio_java大文件处理_”显然专注于通过Java NIO实现大文件处理,下面我们将详细探讨相关的知识点。 1. **Java NIO基础**:NIO的核心组件包括通道(Channels)、缓冲区...
在给定的压缩包文件中,我们关注的是"FastCopyFile.java"、"UseFloatBuffer.java"以及NIO中的文件锁功能。 首先,让我们详细了解一下`FastCopyFile.java`。这个文件很可能是一个示例程序,演示了如何使用Java NIO...