【原創】java NIO FileChannel 學習筆記 FileChannel實現分析 即FileChannelImpl分析


上文已經說了FileChannel是一個抽象類,FileChannelImpl是其實現,接下來介紹FileChannelImpl,參考代碼來自OpenJDK7

首先 

public class FileChannelImpl extends FileChannel

該類的成員有:

// Memory allocation size for mapping buffers
private static final long allocationGranularity;

// Used to make native read and write calls
private final FileDispatcher nd;

// File descriptor
private final FileDescriptor fd;

// File access mode (immutable)
private final boolean writable;
private final boolean readable;
private final boolean append;

// Required to prevent finalization of creating stream (immutable)
private final Object parent;

// Thread-safe set of IDs of native threads, for signalling
private final NativeThreadSet threads = new NativeThreadSet(2);

// Lock for operations involving position and size
private final Object positionLock = new Object();

//發現NIO這些類里面好多直接拿一個Object當做鎖用的,沒有用ReentrantLock等顯式鎖,畢竟1.6之后內置鎖的效率已經得到了提升,並且更方便

 

 

關於FileDescriptor的描述:

Instances of the file descriptor class serve as an opaque handle to the underlying machine-specific structure representing an open file, an open socket, or another source or sink of bytes. The main practical use for a file descriptor is to create a FileInputStream or FileOutputStream to contain it.

Applications should not create their own file descriptors.

接下來介紹私有構造函數

private FileChannelImpl(FileDescriptor fd, boolean readable,
boolean writable, boolean append, Object parent)
{
this.fd = fd;
this.readable = readable;
this.writable = writable;
this.append = append;
this.parent = parent;
this.nd = new FileDispatcherImpl(append);
}

既然是私有的那么我們只能使用Open來獲取一個實例,關於參數總的parent 我認為是這個FileChannel對應的FileInputStream之類。

// Used by FileInputStream.getChannel() and RandomAccessFile.getChannel()
public static FileChannel open(FileDescriptor fd,
boolean readable, boolean writable,
Object parent)
{
return new FileChannelImpl(fd, readable, writable, false, parent);
}

// Used by FileOutputStream.getChannel
public static FileChannel open(FileDescriptor fd,
boolean readable, boolean writable,
boolean append, Object parent)
{
return new FileChannelImpl(fd, readable, writable, append, parent);
}

接下來將介紹FileChannel的close 、read 和write position方法

先說close方法是AbstractInterruptibleChannel中定義的方法。一下是關於該類的簡單信息

public abstract class AbstractInterruptibleChannel
implements Channel, InterruptibleChannel

該類中close的定義:

public final void close() throws IOException {
synchronized (closeLock) {
  if (!open)
  return;
  open = false;
  implCloseChannel();
  }
}

先說closeLock,  聲明為一個final 類成員 private final Object closeLock = new Object();

再說implCloseChannel()       protected abstract void implCloseChannel() throws IOException;顯而易見繼承該抽象類的類來實現該抽象方法

FileChannelImpl的implCloseChannel() 方法

protected void implCloseChannel() throws IOException {
// Release and invalidate any locks that we still hold
if (fileLockTable != null) {
  for (FileLock fl: fileLockTable.removeAll()) {
  synchronized (fl) {
    if (fl.isValid()) {
            nd.release(fd, fl.position(), fl.size());
            ((FileLockImpl)fl).invalidate();
      }
    }
   }
}

nd.preClose(fd);
threads.signalAndWait();

if (parent != null) {

// Close the fd via the parent stream's close method. The parent
// will reinvoke our close method, which is defined in the
// superclass AbstractInterruptibleChannel, but the isOpen logic in
// that method will prevent this method from being reinvoked.
//
((java.io.Closeable)parent).close();
} else {
nd.close(fd);
}

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM