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