初始化
//根据OS区分实现 System.getProperty("os.name").toLowerCase(); Utils.isWindows() ? new WindowsFileSystem(this) : new FileSystemImpl(this);
异步操作实现
FileSystemImpl 内部类 BlockingAction, 使用internalBlocking Pool 执行文件阻塞操作, xxxBlocking相关方法在当前主线程操作造成阻塞,尽量避免
protected abstract class BlockingAction<T> implements Action<T> { private final Handler<AsyncResult<T>> handler;//回调 handler protected final ContextImpl context;//上下文,作用:处理完成回调到同一线程 public BlockingAction(Handler<AsyncResult<T>> handler) { this.handler = handler; this.context = vertx.getOrCreateContext(); } /** * Run the blocking action using a thread from the worker pool. */ public void run() { context.executeBlocking(this, handler); //使用 internalBlocking Pool执行任务 } }
AsyncFileImpl
FileSystemImpl 的open方法返回的AsyncFileImpl,记住调用close方法,防止文件句柄泄露, linux可使用 lsof 工具查看当前file descriptor情况
AsyncFileImpl(VertxInternal vertx, String path, OpenOptions options, ContextImpl context) { if (!options.isRead() && !options.isWrite()) { throw new FileSystemException("Cannot open file for neither reading nor writing"); } this.vertx = vertx; Path file = Paths.get(path); /**定义open属性*/ HashSet<OpenOption> opts = new HashSet<>(); if (options.isRead()) opts.add(StandardOpenOption.READ); if (options.isWrite()) opts.add(StandardOpenOption.WRITE); if (options.isCreate()) opts.add(StandardOpenOption.CREATE); if (options.isCreateNew()) opts.add(StandardOpenOption.CREATE_NEW); if (options.isSync()) opts.add(StandardOpenOption.SYNC); if (options.isDsync()) opts.add(StandardOpenOption.DSYNC); if (options.isDeleteOnClose()) opts.add(StandardOpenOption.DELETE_ON_CLOSE); if (options.isSparse()) opts.add(StandardOpenOption.SPARSE); if (options.isTruncateExisting()) opts.add(StandardOpenOption.TRUNCATE_EXISTING); try { //获取文件权限字符 linux 下 ls -al 文件权限标识 rwx if (options.getPerms() != null) { //将权限字符转化为FileAttribute属性 FileAttribute<?> attrs = PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString(options.getPerms())); /**使用worker Pool,而不是用默认的Executors.newCachedThreadPool(threadFactory), 原则:vertx使用少量线程处理大并发,吞吐量优先*/ ch = AsynchronousFileChannel.open(file, opts, vertx.getWorkerPool(), attrs); } else { ch = AsynchronousFileChannel.open(file, opts, vertx.getWorkerPool()); } //属性为"追加"获取大小做为 write index if (options.isAppend()) writePos = ch.size(); } catch (IOException e) { throw new FileSystemException(e); } //上下文,作用:处理完成回调到同一线程 this.context = context; }