关于FileChannel的获取方式之open方法详解
Posted yangmin86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于FileChannel的获取方式之open方法详解相关的知识,希望对你有一定的参考价值。
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方法详解的主要内容,如果未能解决你的问题,请参考以下文章