Java NIO - AsynchronousFileChannel

Comme nous savons que Java NIO prend en charge la concurrence et le multi-threading, ce qui nous permet de traiter différents canaux simultanément en même temps, l'API qui en est responsable dans le package Java NIO est AsynchronousFileChannel qui est défini sous le package de canaux NIO. pour AsynchronousFileChannel est java.nio.channels.AsynchronousFileChannel.

AsynchronousFileChannel est similaire à celui du FileChannel du NIO, sauf que ce canal permet aux opérations de fichier de s'exécuter de manière asynchrone contrairement à une opération d'E / S synchrone dans laquelle un thread entre dans une action et attend que la requête soit terminée. par plusieurs threads simultanés.

En asynchrone, la demande est transmise par thread au noyau du système d'exploitation pour le faire pendant que le thread continue de traiter un autre travail.Une fois le travail du noyau terminé, il signale le thread, puis le thread a reconnu le signal et interrompt le travail en cours et traite le Travail d'E / S selon les besoins.

Pour obtenir la concurrence, ce canal propose deux approches, dont une en renvoyant un java.util.concurrent.Future object et l'autre passe à l'opération un objet de type java.nio.channels.CompletionHandler.

Nous comprendrons les deux approches à l'aide d'exemples une par une.

  • Future Object - Dans ce cas, une instance de Future Interface est renvoyée depuis le canal. get() qui retourne le statut de l'opération gérée de manière asynchrone sur la base de laquelle l'exécution d'une autre tâche pourrait être décidée.Nous pouvons également vérifier si la tâche est terminée ou non en appelant son isDone méthode.

Exemple

L'exemple suivant montre comment utiliser l'objet Future et effectuer des tâches de manière asynchrone.

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

Production

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 -

    Cette approche est assez simple, car nous utilisons l'interface CompletionHandler et remplace ses deux méthodes, l'une est completed() méthode qui est appelée lorsque l'opération d'E / S se termine avec succès et que l'autre est failed() qui est appelée si les opérations d'E / S échouent. Dans ce cas, un gestionnaire est créé pour consommer le résultat d'une opération d'E / S asynchrone, car une fois qu'une tâche est terminée, seul le gestionnaire a des fonctions qui sont exécutées.

Exemple

L'exemple suivant montre comment utiliser CompletionHandler pour effectuer des tâches de manière asynchrone.

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

Production

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.