/** * Copyright 2015-2017 Valery Silaev (http://vsilaev.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package net.tascalate.async.examples.nio; import static net.tascalate.async.CallContext.async; import static net.tascalate.async.CallContext.await; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.nio.ByteBuffer; import java.nio.channels.FileLock; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.time.LocalTime; import java.util.Collections; import java.util.concurrent.CompletionStage; import net.tascalate.async.async; import net.tascalate.nio.channels.AsynchronousFileChannel; public class AsyncAwaitNioFileChannelDemo { public static void main(final String[] argv) throws Exception { final AsyncAwaitNioFileChannelDemo demo = new AsyncAwaitNioFileChannelDemo(); final CompletionStage<String> result = demo.processFile("./.project"); System.out.println("Returned to caller " + LocalTime.now()); final CompletionStage<?> waiter = result.whenComplete((r, e) -> { if ( e != null ) { System.out.println("Error " + LocalTime.now()); e.printStackTrace(System.out); } else { System.out.println("Result " + LocalTime.now()); System.out.println(r); } }); // Need to wait because NIO uses daemon threads that do not prevent program exit System.out.println("Start waiting for result to prevent program close..."); waiter.toCompletableFuture().join(); } public @async CompletionStage<String> processFile(final String fileName) throws IOException { final Path path = Paths.get(new File(fileName).toURI()); try ( final AsynchronousFileChannel file = AsynchronousFileChannel.open(path, Collections.singleton(StandardOpenOption.READ), null); final FileLock lock = await(file.lockAll(true)) ) { System.out.println("In process, shared lock: " + lock); final ByteBuffer buffer = ByteBuffer.allocateDirect((int)file.size()); await( file.read(buffer, 0L) ); System.out.println("In process, bytes read: " + buffer); buffer.rewind(); final String result = processBytes(buffer); return async(result); } catch (final IOException ex) { ex.printStackTrace(System.out); throw ex; } } private String processBytes(final ByteBuffer buffer) throws IOException { final StringBuilder result = new StringBuilder(); final char[] chars = new char[4096]; try (final InputStreamReader in = new InputStreamReader(new ByteBufferInputStream(buffer))) { int count = 0; while( (count = in.read(chars)) > 0) { result.append(chars, 0, count); }; return result.toString(); } } }