Java Nio Buffer 九

2018/01/10 Java

Java Nio Buffer 九

文件通道

FileChannel 类可以实现常用的 read,write 以及 scatter/gather 操作,同时它也提供了很多专用于文件的新方法。
类的层次结构图如下:
图一

文件通道总是阻塞式的,因此不能被置于非阻塞模式。现代操作系统都有复杂的缓存和预取机制,使得本地磁盘 I/O 操作延迟很少。
NAS一般而言延迟会多些,不过却也因该优化而受益。面向流的 I/O 的非阻塞范例对于面向文件的操作并无多大意义,这是由不同类型的 I/O 不同性质造成的。文件 I/O,最强大之处在于异步 I/O(asynchronous I/O),它允许一个进程可以从操作系统请求一个或多个 I/O 操作而不必等待这些操作的完成。发起请求的进程之后会收到它请求的 I/O 操作已完成的通知。异步 I/O 是一种高级性能,当前的很多操作系统都还不具备。以后的 NIO 增强也会把异步 I/O 纳入考虑范围。
FileChannel对象不能直接创建。一个FileChannel实例只能通过在一个 打开的file对象(RandomAccessFile、FileInputStream或 FileOutputStream)上调用getChannel( )方法获取。
FileChannel类的签名如下:

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)
}

只要有可能,FileChannel 都会尝试使用本地 I/O 服务。FileChannel 类本身是抽象的,getChannel( )方法获取的实际对象是一个具体子类(subclass)的一个实例 (instance),该子类可能使用本地代码来实现以上 API 方法中的一些或全部。

FileChannel 对象是线程安全(thread-safe)的。多个进程可以在同一个实例上并发调用方法而 不会引起任何问题,不过并非所有的操作都是多线程的(multithreaded)。影响通道位置或者影响 文件大小的操作都是单线程的(single-threaded)。如果有一个线程已经在执行会影响通道位置或文 件大小的操作,那么其他尝试进行此类操作之一的线程必须等待。并发行为也会受到底层的操作系 统或文件系统影响。FileChannel 是一个反映 Java 虚拟机外部一个具体对象的抽象。FileChannel 类保证同一个 Java 虚拟机上的所有实例看到的某个文件的视图均是一致的,但是 Java 虚拟机却不能对超出它控制范围的因素提供担保。

Show Disqus Comments

Search

    Table of Contents