A channel that supports asynchronous I/O operations. Asynchronous I/O operations will usually take one of two forms:
Future operation(…)
void operation(… A attachment, CompletionHandler<V,? super A> handler)
In the first form, the methods defined by the Future interface may be used to check if the operation has completed, wait for its completion, and to retrieve the result.
In the second form, a CompletionHandler is invoked to consume the result of the I/O operation when it completes or fails.
An asynchronous file channel does not have a current position within the file. Instead, the file position is specified to each read and write method that initiates asynchronous operations.
// create the AsynchronousFileChannel // 创建 AsynchronousFileChannel 对象 try { return WindowsAsynchronousFileChannelImpl.open(fdObj, flags.read, flags.write, pool); } catch (IOException x) { // IOException is thrown if the file handle cannot be associated // with the completion port. All we can do is close the file. long handle = fdAccess.getHandle(fdObj); CloseHandle(handle); throw x; } }
// SimpleAsynchronousFileChannelImpl.implRead <A> Future<Integer> implRead(final ByteBuffer dst, finallong position, final A attachment, final CompletionHandler<Integer,? super A> handler) { if (position < 0) thrownew IllegalArgumentException("Negative position"); if (!reading) thrownew NonReadableChannelException(); if (dst.isReadOnly()) thrownew IllegalArgumentException("Read-only buffer");
// complete immediately if channel closed or no space remaining if (!isOpen() || (dst.remaining() == 0)) { Throwable exc = (isOpen()) ? null : new ClosedChannelException(); if (handler == null) return CompletedFuture.withResult(0, exc); Invoker.invokeIndirectly(handler, attachment, 0, exc, executor); returnnull; }
// 创建 Future 对象 final PendingFuture<Integer,A> result = (handler == null) ? new PendingFuture<Integer,A>(this) : null; // 创建 task 对象 Runnable task = new Runnable() { publicvoidrun(){ int n = 0; Throwable exc = null;
int ti = threads.add(); try { begin(); do { n = IOUtil.read(fdObj, dst, position, nd, null); } while ((n == IOStatus.INTERRUPTED) && isOpen()); if (n < 0 && !isOpen()) thrownew AsynchronousCloseException(); } catch (IOException x) { if (!isOpen()) x = new AsynchronousCloseException(); exc = x; } finally { end(); threads.remove(ti); } // 为不同的API提供接口
if (handler == null) { // 如果 handler 为 null 则 API 的形式应该是 // Future<V> operation(...) // 也就是说这个 result 将会作为 operation // 的返回值 Future ,result 的类型是 PendingFuture // 就是 Future 的子类 // result.setResult 将会使得所有在 result 这个 Future // 上进行等待的线程进行通知, result.setResult(n, exc); } else { // 如果 handler 不为null, 则 上层API的形式应该是: // void operation(... A attachment, CompletionHandler<V,? super A> handler) // 这个方法将对 handler 进行回调 Invoker.invokeUnchecked(handler, attachment, n, exc); } } };
// 提交任务 executor.execute(task); return result; }
// AsynchronousFileChannelImpl.read @Override publicfinal Future<Integer> read(ByteBuffer dst, long position){ return implRead(dst, position, null, null); } @Override publicfinal <A> voidread(ByteBuffer dst, long position, A attachment, CompletionHandler<Integer,? super A> handler) { if (handler == null) thrownew NullPointerException("'handler' is null"); implRead(dst, position, attachment, handler); }
// Invoker.invokeUnchecked static <V,A> voidinvokeUnchecked(CompletionHandler<V,? super A> handler, A attachment, V value, Throwable exc) { if (exc == null) { // 未发生异常,正常完成 handler.completed(value, attachment); } else { // 发生异常,调用 failed handler.failed(exc, attachment); }