Java-nio-asynchronous-filechannel

提供:Dev Guides
移動先:案内検索

Java NIO-AsynchronousFileChannel

Java NIOは並行性とマルチスレッドをサポートしているため、異なるチャネルを同時に同時に処理できるため、Java NIOパッケージでこれを担当するAPIは、NIOチャネルパッケージで定義されるAsynchronousFileChannelです。 AsynchronousFileChannelの場合は java.nio.channels.AsynchronousFileChannel です。

AsynchronousFileChannelはNIOのFileChannelに似ていますが、スレッドがアクションを開始してリクエストが完了するまで待機する同期I/O操作とは異なり、このチャネルではファイル操作を非同期に実行できる点が異なります。したがって、非同期チャンネルは安全に使用できます。複数の同時スレッドによる。

非同期では、要求はスレッドによってオペレーティングシステムのカーネルに渡され、スレッドが別のジョブの処理を続行している間に実行されます。カーネルのジョブが完了すると、スレッドに信号を送り、スレッドは信号に応答して現在のジョブを中断し、処理します必要に応じてI/Oジョブ。

並行性を実現するために、このチャネルは、* java.util.concurrent.Futureオブジェクト*を返す方法と、 java.nio.channels.CompletionHandler 型のオブジェクトを操作に渡す方法の2つの方法を提供します。

例を使用して、両方のアプローチを1つずつ理解します。

  • Future Object -これには、チャネルからFuture Interfaceのインスタンスが返されます。FutureInterfaceには、他のタスクのさらなる実行に基づいて非同期的に処理される操作のステータスを返す* get()メソッドがありますまた、 *isDone メソッドを呼び出すことで、タスクが完了したかどうかを確認できます。

次の例は、Futureオブジェクトの使用方法と非同期でタスクを実行する方法を示しています。

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

出力

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?
  • 完了ハンドラ- +このアプローチは非常に簡単です。CompletionHandlerインターフェースを使用し、I/O操作が正常に完了したときに呼び出される* completed()メソッドと、次の場合に呼び出される failed()*メソッドの2つのメソッドをオーバーライドしますI/O操作は失敗します。この場合、タスクが完了するとハンドラーのみが実行される機能を持つため、非同期I/O操作の結果を使用するハンドラーが作成されます。

次の例は、CompletionHandlerを使用して非同期にタスクを実行する方法を示しています。

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

出力

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.