Java NIO - AsynchronousFileChannel

Come sappiamo, Java NIO supporta la concorrenza e il multi-threading che ci consente di gestire diversi canali contemporaneamente allo stesso tempo.Quindi l'API responsabile di questo nel pacchetto Java NIO è AsynchronousFileChannel che è definito sotto il pacchetto dei canali NIO. per AsynchronousFileChannel è java.nio.channels.AsynchronousFileChannel.

AsynchronousFileChannel è simile a quello del FileChannel di NIO, tranne per il fatto che questo canale consente alle operazioni sui file di essere eseguite in modo asincrono a differenza dell'operazione di I / O sincrona in cui un thread entra in un'azione e attende fino al completamento della richiesta. da più thread simultanei.

In modalità asincrona la richiesta viene passata dal thread al kernel del sistema operativo per eseguirla mentre il thread continua a elaborare un altro lavoro.Una volta completato il lavoro del kernel, segnala il thread quindi il thread ha riconosciuto il segnale e interrompe il lavoro corrente ed elabora il Lavoro di I / O secondo necessità.

Per ottenere la concorrenza questo canale fornisce due approcci che includono uno come restituzione di un file java.util.concurrent.Future object e altro è Passare all'operazione un oggetto di tipo java.nio.channels.CompletionHandler.

Comprenderemo entrambi gli approcci con l'aiuto di esempi uno per uno.

  • Future Object - In questo viene restituita un'istanza di Future Interface dal canale, mentre in Future Interface c'è get() metodo che restituisce lo stato dell'operazione che viene gestito in modo asincrono in base al quale potrebbe essere decisa l'ulteriore esecuzione di altre attività.Possiamo anche verificare se l'attività è completata o meno chiamando il suo isDone metodo.

Esempio

L'esempio seguente mostra come utilizzare l'oggetto Future e eseguire le attività in modo asincrono.

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();
   }
}

Produzione

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 -

    Questo approccio è piuttosto semplice poiché in questo usiamo l'interfaccia CompletionHandler e sovrascrive i suoi due metodi uno è completed() metodo che viene richiamato quando l'operazione di I / O viene completata correttamente e l'altro è failed() che viene richiamato se le operazioni di I / O falliscono. In questo viene creato un gestore per consumare il risultato di un'operazione di I / O asincrona poiché una volta completata un'attività, solo il gestore ha funzioni che vengono eseguite.

Esempio

L'esempio seguente mostra come utilizzare CompletionHandler per eseguire attività in modo asincrono.

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();
   }
}

Produzione

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.