1. 程式人生 > >關於FileChannel的獲取方式之open方法詳解

關於FileChannel的獲取方式之open方法詳解

mismatch 詳解 -m jdk1.8 eclipse all match try sin

FileChannel.open(Path path, OpenOption... options);

例子使用JDK1.8

FileChannel open方法源碼:

public static FileChannel open(Path path, OpenOption... options)
        throws IOException
    {
        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
        Collections.addAll(set, options);
        return open(path, set, NO_ATTRIBUTES);
}

 

繼續查看源碼:

public static FileChannel open(Path path,
                                   Set<? extends OpenOption> options,
                                   FileAttribute<?>... attrs)
        throws IOException
    {
     //FileChannel的對象,由FileSystemProvider提供 FileSystemProvider
provider = path.getFileSystem().provider(); return provider.newFileChannel(path, options, attrs); }

FileChannel的對象,看似由FileSystemProvider提供,我們繼續跟代碼

 public FileChannel newFileChannel(Path path,
                                      Set<? extends OpenOption> options,
                                      FileAttribute
<?>... attrs) throws IOException { throw new UnsupportedOperationException(); }

方法到這一步我們發現,該方法其實是一個空方法,我們查看FileSystemProvider的類結構,看是否在其子類中會有對應實現,如下:

技術分享圖片

我們可以看FileSystemProvider的實現類有兩個,其中ZipFileSystemProvider提供了newFileChannel的方法實現,但是由於該類不是JDK的核心類,該類位於jdk1.8.0_131\jre\lib\ext\zipfs.jar,所有沒有提供源碼,不過我們可以通過反編譯工具進行跟進去:

//ZipFileSystemProvider方法newFileChannel
//ZipFileSystemProvider類提供的方法newFileChannel其實還不是類的實現,繼續看toZipPath方法
public
FileChannel newFileChannel(Path paramPath, Set<? extends OpenOption> paramSet, FileAttribute<?>... paramVarArgs) throws IOException { return toZipPath(paramPath).newFileChannel(paramSet, paramVarArgs); }

ZipFileSystemProvider類提供的方法newFileChannel其實還不是類的實現,繼續看toZipPath方法:

//ZipFileSystemProvider方法toZipPath
//我們看到這裏的方法返回的是一個ZipPath類,也就是說上面的代碼 toZipPath(paramPath).newFileChannel(paramSet, paramVarArgs);

//可以理解為ZipPath.newFileChannel(),沒辦法繼續看ZipPath類
static
final ZipPath toZipPath(Path paramPath) { if (paramPath == null) { throw new NullPointerException(); } if (!(paramPath instanceof ZipPath)) { throw new ProviderMismatchException(); } return (ZipPath)paramPath; }

我們看到這裏的方法返回的是一個ZipPath類,也就是說上面的代碼 toZipPath(paramPath).newFileChannel(paramSet, paramVarArgs);以理解為ZipPath.newFileChannel(),沒辦法繼續看ZipPath

 
//截取部分類屬性
public class ZipPath
implements Path
{
//2:繼續跟ZipFileSystem類
private final ZipFileSystem zfs;
private final byte[] path;
private volatile int[] offsets;
private int hashcode = 0;

FileChannel newFileChannel(Set<? extends OpenOption> paramSet, FileAttribute<?>... paramVarArgs)
throws IOException
{
   //1:老套路,繼續看zfs屬性是個啥
return this.zfs.newFileChannel(getResolvedPath(), paramSet, paramVarArgs);
}

}

繼續ZipFileSystem源碼:

//ZipFileSystem類方法newFileChannel
//我們終於找到了FileChannel在哪給我們實現了,我們可以看到這裏是new了一個FileChannel(){},一般情況下我們知道new一個對象的語法:
// ClassA a = new Class(); 其實這裏是省略了大括號 ClassA a = new Class(){}; 完整的寫法在這,但是有個一問題
FileChannel newFileChannel(byte[] paramArrayOfByte, Set<? extends OpenOption> paramSet, FileAttribute<?>... paramVarArgs) throws IOException { checkOptions(paramSet); final boolean bool1 = (paramSet.contains(StandardOpenOption.WRITE)) || (paramSet.contains(StandardOpenOption.APPEND)); beginRead(); try { new FileChannel() { ... return localFileChannel.write(paramAnonymousArrayOfByteBuffer, paramAnonymousInt1, paramAnonymousInt2); ... public int read(ByteBuffer paramAnonymousByteBuffer) throws IOException { return localFileChannel.read(paramAnonymousByteBuffer); } }; } finally { endRead(); } }

 

關於FileChannel的獲取方式之open方法詳解