Java NIO - AsynchronousFileChannel

Seperti yang kita ketahui bahwa Java NIO mendukung konkurensi dan multi-threading yang memungkinkan kita untuk menangani saluran yang berbeda secara bersamaan pada saat yang sama.Jadi API yang bertanggung jawab untuk ini dalam paket Java NIO adalah AsynchronousFileChannel yang didefinisikan di bawah paket saluran NIO. Oleh karena itu nama yang memenuhi syarat untuk AsynchronousFileChannel adalah java.nio.channels.AsynchronousFileChannel.

AsynchronousFileChannel mirip dengan NIO's FileChannel, kecuali bahwa saluran ini memungkinkan operasi file untuk dijalankan secara asynchronous tidak seperti operasi I / O sinkron di mana thread masuk ke dalam suatu tindakan dan menunggu sampai permintaan selesai. Dengan demikian saluran asinkron aman untuk digunakan dengan beberapa utas bersamaan.

Dalam asynchronous, permintaan diteruskan oleh thread ke kernel sistem operasi untuk menyelesaikannya sementara thread terus memproses pekerjaan lain. Setelah pekerjaan kernel selesai, ia memberi sinyal kepada thread maka thread mengenali sinyal dan mengganggu pekerjaan saat ini dan memproses Pekerjaan I / O sesuai kebutuhan.

Untuk mencapai konkurensi, saluran ini menyediakan dua pendekatan yang mencakup satu sebagai mengembalikan a java.util.concurrent.Future object dan lainnya Meneruskan ke operasi sebuah objek bertipe java.nio.channels.CompletionHandler.

Kami akan memahami kedua pendekatan dengan bantuan contoh satu per satu.

  • Future Object - Dalam contoh ini Antarmuka Masa Depan dikembalikan dari saluran. Di antarmuka Masa Depan ada get() metode yang mengembalikan status operasi yang ditangani secara asinkron atas dasar eksekusi lebih lanjut dari tugas lain dapat diputuskan. Kita juga dapat memeriksa apakah tugas selesai atau tidak dengan memanggilnya isDone metode.

Contoh

Contoh berikut menunjukkan cara menggunakan objek Future dan melakukan tugas secara asinkron.

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

Keluaran

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 -

    Pendekatan ini cukup sederhana karena dalam hal ini kami menggunakan antarmuka CompletionHandler dan mengganti dua metode yang satu ini completed() metode yang dipanggil ketika operasi I / O selesai dengan sukses dan lainnya failed() metode yang dipanggil jika operasi I / O gagal. Dalam hal ini penangan dibuat untuk menggunakan hasil dari operasi I / O asinkron seperti setelah tugas selesai maka hanya penangan yang memiliki fungsi yang dijalankan.

Contoh

Contoh berikut menunjukkan cara menggunakan CompletionHandler untuk melakukan tugas secara asynchronous.

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

Keluaran

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.