Java NIO - AsynchronousFileChannel
Java NIO'nun eşzamanlılığı ve çoklu iş parçacığını desteklediğini bildiğimiz için aynı anda farklı kanallarla aynı anda ilgilenmemize izin verir.Yani Java NIO paketinde bundan sorumlu olan API, NIO kanalları paketi altında tanımlanan AsynchronousFileChannel'dir. AsynchronousFileChannel için java.nio.channels.AsynchronousFileChannel.
AsynchronousFileChannel, NIO'nun FileChannel'ına benzer, ancak bu kanal, bir iş parçacığının bir eyleme girdiği ve istek tamamlanana kadar beklediği zaman uyumlu G / Ç işleminden farklı olarak dosya işlemlerinin eşzamansız olarak yürütülmesine olanak tanıması dışında. birden çok eşzamanlı iş parçacığı tarafından.
Eşzamansız olarak, iş parçacığı başka bir işi işlemeye devam ederken, iş parçacığı tarafından işletim sisteminin çekirdeğine iletilir. Çekirdek işi tamamlandığında, iş parçacığına sinyal verir, ardından iş parçacığı sinyali kabul eder ve mevcut işi keser ve işleme koyar. Gerektiği gibi I / O işi.
Eşzamanlılık elde etmek için bu kanal, birini geri dönüş olarak içeren iki yaklaşım sunar. java.util.concurrent.Future object ve diğeri de işleme türünde bir nesne geçirmektir. java.nio.channels.CompletionHandler.
Her iki yaklaşımı da örnekler yardımıyla tek tek anlayacağız.
Future Object - Bunda bir Gelecek Arayüz örneği kanaldan döndürülür.Gelecek arayüzde var get() Diğer görevin daha fazla yürütülmesine karar verilebilmesi temelinde eşzamansız olarak işlenen işlemin durumunu döndüren yöntem.Ayrıca görevin tamamlanıp tamamlanmadığını da isDone yöntem.
Misal
Aşağıdaki örnek, Future nesnesinin nasıl kullanılacağını ve zaman uyumsuz olarak nasıl görev yapılacağını gösterir.
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();
}
}
Çıktı
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 -
Bu yaklaşım oldukça basittir, çünkü burada CompletionHandler arayüzünü kullanıyoruz ve iki yöntemini geçersiz kılıyoruz. completed() G / Ç işlemi başarıyla tamamlandığında ve diğeri olduğunda çağrılan yöntem failed() G / Ç işlemleri başarısız olursa çağrılan yöntem.Burada, bir görev tamamlandıktan sonra eşzamansız bir G / Ç işleminin sonucunu tüketmek için bir işleyici oluşturulur, ardından yalnızca işleyicinin çalıştırılan işlevleri vardır.
Misal
Aşağıdaki örnek, zaman uyumsuz olarak görev yapmak için CompletionHandler'ın nasıl kullanılacağını gösterir.
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();
}
}
Çıktı
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.