转载

Java NIO 之 Channel 中

FileChannel

Java NIO 之 Channel 中

FileChannel 总是阻塞的,因此不能被设置成非阻塞模式。

FileChannel 对象不能直接创建。一个 FileChannel 实例只能通过在一个打开的 file 对象(RandomAccessFile、FileInputStream或 FileOutputStream)上调用 getChannel() 方法 获取。

public abstract class FileChannel extends AbstractInterruptibleChannel implements ByteChannel,   GatheringByteChannel, ScatteringByteChannel {  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 类本身是抽象的, getChannel() 方法获取的实际对象是一个具体子类的一个实例 ,该子类可能使用本地代码来实现以上 API 方法中的一些或全部。

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

FileChannel 是一个反映 Java 虚拟机外部一个具体对象的抽象。

FileChannel 类保证同一个 Java 虚拟机上的所有实例看到的某个文件的视图均是一致的。

每个 FileChannel 对象都同一个文件描述符(file descriptor)有一对一的关系。

FileChannel、RandomAccessFile 和 POSIX I/O system calls 三者在 方法上的对应关系。

FileChannel RandomAccessFile POSIX system call
read( ) read( ) read( )
write( ) write( ) write( )
size( ) length( ) fstat( )
position( ) getFilePointer( ) lseek( )
position (long newPosition) seek( ) lseek( )
truncate( ) setLength( ) ftruncate( )
force( ) getFD().sync( ) fsync( )

每个 FileChannel 都有一个 position 值来决定文件中哪一处的数据接下来被读或者写。

如果试将通道 position 设置为一个负值会导致 java.lang.IllegalArgumentException 异常。

把 position 设置到超出文件 ,这样做会把 position 设置为指定值而不改变文件大小。

FileChannel 位置(position)是从底层的文件 述符获得的,该 position 同时被作为通道引用 获取来源的文件对象共享。这也就意味着一个对象对该 position 的更新可以被另一个对象看到:

RandomAccessFile randomAccessFile = new RandomAccessFile ("filename", "r");  randomAccessFile.seek (1000);  FileChannel fileChannel = randomAccessFile.getChannel( );  // This will print "1000" System.out.println ("file pos: " + fileChannel.position( ));  randomAccessFile.seek (500);  // This will print "500" System.out.println ("file pos: " + fileChannel.position( ));  fileChannel.position (200);  // This will print "200" System.out.println ("file pos: " + randomAccessFile.getFilePointer( )); 

当需要减少一个文件的 size 时,truncate( )方法会 您所指定的新 size 值之外的所有数据。

如果当前 size 大于新 size,超出新 size 的所有字节都会被丢弃。

如果提供的新 size 值大于或等于当前的文件 size 值,该文件不会被修改。

调用 truncate() 方法后 position 会被设置成提供的新 size。

force() 方法告诉通道强制将全部待定的修改都应用到磁盘的文件上。所有的现代文件系统都会缓存数据和延迟磁盘文件更新以提高性能。调用 force( )方法要求文件的所有待定修改立即同步到磁盘。

【参考资料】

  1. Java Nio

—EOF—

原文  http://renchx.com/javanio-channel2
正文到此结束
Loading...