Java NIO - AsynchronousFileChannel
Da wir wissen, dass Java NIO Parallelität und Multithreading unterstützt, wodurch wir gleichzeitig mit verschiedenen Kanälen arbeiten können. Die API, die im Java NIO-Paket dafür verantwortlich ist, ist AsynchronousFileChannel, das unter NIO-Kanalpaket definiert ist für AsynchronousFileChannel ist java.nio.channels.AsynchronousFileChannel.
AsynchronousFileChannel ähnelt dem FileChannel des NIO, mit der Ausnahme, dass dieser Kanal die asynchrone Ausführung von Dateivorgängen ermöglicht, im Gegensatz zu synchronen E / A-Vorgängen, bei denen ein Thread eine Aktion ausführt und wartet, bis die Anforderung abgeschlossen ist. Auf diese Weise können asynchrone Kanäle sicher verwendet werden durch mehrere gleichzeitige Threads.
Asynchron wird die Anforderung per Thread an den Kernel des Betriebssystems übergeben, um sie auszuführen, während der Thread weiterhin einen anderen Job verarbeitet. Sobald der Job des Kernels erledigt ist, signalisiert er dem Thread, dann bestätigt der Thread das Signal und unterbricht den aktuellen Job und verarbeitet den E / A-Job nach Bedarf.
Um Parallelität zu erreichen, bietet dieser Kanal zwei Ansätze, darunter einen als Rückgabe von a java.util.concurrent.Future object und eine andere ist das Übergeben eines Objekts vom Typ an die Operation java.nio.channels.CompletionHandler.
Wir werden beide Ansätze anhand von Beispielen einzeln verstehen.
Future Object - In diesem Fall wird eine Instanz von Future Interface vom Kanal zurückgegeben. In Future Interface gibt es get() Methode, die den Status der Operation zurückgibt, die asynchron behandelt wird, auf deren Grundlage eine weitere Ausführung einer anderen Aufgabe entschieden werden könnte. Wir können auch überprüfen, ob die Aufgabe abgeschlossen ist oder nicht, indem wir ihre aufrufen isDone Methode.
Beispiel
Das folgende Beispiel zeigt, wie Future-Objekte verwendet und Aufgaben asynchron ausgeführt werden.
package com.java.nio;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public class FutureObject {
public static void main(String[] args) throws Exception {
readFile();
}
private static void readFile() throws IOException, InterruptedException, ExecutionException {
String filePath = "D:fileCopy.txt";
printFileContents(filePath);
Path path = Paths.get(filePath);
AsynchronousFileChannel channel =AsynchronousFileChannel.open(path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(400);
Future<Integer> result = channel.read(buffer, 0); // position = 0
while (! result.isDone()) {
System.out.println("Task of reading file is in progress asynchronously.");
}
System.out.println("Reading done: " + result.isDone());
System.out.println("Bytes read from file: " + result.get());
buffer.flip();
System.out.print("Buffer contents: ");
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
System.out.println(" ");
buffer.clear();
channel.close();
}
private static void printFileContents(String path) throws IOException {
FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr);
String textRead = br.readLine();
System.out.println("File contents: ");
while (textRead != null) {
System.out.println(" " + textRead);
textRead = br.readLine();
}
fr.close();
br.close();
}
}
Ausgabe
File contents:
To be or not to be?
Task of reading file is in progress asynchronously.
Task of reading file is in progress asynchronously.
Reading done: true
Bytes read from file: 19
Buffer contents: To be or not to be?
Completion Handler - -
Dieser Ansatz ist ziemlich einfach, da wir hier die CompletionHandler-Schnittstelle verwenden und die beiden Methoden überschreiben, die eine ist completed() Methode, die aufgerufen wird, wenn die E / A-Operation erfolgreich abgeschlossen wurde und andere ist failed() Methode, die aufgerufen wird, wenn die E / A-Operationen fehlschlagen. Hierbei wird ein Handler erstellt, um das Ergebnis einer asynchronen E / A-Operation zu verarbeiten, da nach Abschluss einer Aufgabe nur der Handler Funktionen hat, die ausgeführt werden.
Beispiel
Das folgende Beispiel zeigt, wie CompletionHandler für asynchrone Aufgaben verwendet wird.
package com.java.nio;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class CompletionHandlerDemo {
public static void main (String [] args) throws Exception {
writeFile();
}
private static void writeFile() throws IOException {
String input = "Content to be written to the file.";
System.out.println("Input string: " + input);
byte [] byteArray = input.getBytes();
ByteBuffer buffer = ByteBuffer.wrap(byteArray);
Path path = Paths.get("D:fileCopy.txt");
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
CompletionHandler handler = new CompletionHandler() {
@Override
public void completed(Object result, Object attachment) {
System.out.println(attachment + " completed and " + result + " bytes are written.");
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println(attachment + " failed with exception:");
exc.printStackTrace();
}
};
channel.write(buffer, 0, "Async Task", handler);
channel.close();
printFileContents(path.toString());
}
private static void printFileContents(String path) throws IOException {
FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr);
String textRead = br.readLine();
System.out.println("File contents: ");
while (textRead != null) {
System.out.println(" " + textRead);
textRead = br.readLine();
}
fr.close();
br.close();
}
}
Ausgabe
Input string: Content to be written to the file.
Async Task completed and 34 bytes are written.
File contents:
Content to be written to the file.