Java NIO - AsynchronousFileChannel
Như chúng ta biết rằng Java NIO hỗ trợ đồng thời và đa luồng cho phép chúng ta xử lý đồng thời các kênh khác nhau cùng một lúc. Vì vậy, API chịu trách nhiệm về điều này trong gói Java NIO là AsynchronousFileChannel được định nghĩa trong gói kênh NIO. đối với AsynchronousFileChannel là java.nio.channels.AsynchronousFileChannel.
AsynchronousFileChannel tương tự như kênh FileChannel của NIO, ngoại trừ kênh này cho phép các hoạt động tệp thực thi không đồng bộ không giống như hoạt động I / O đồng bộ trong đó một luồng tham gia vào một hành động và đợi cho đến khi yêu cầu được hoàn thành. bởi nhiều chủ đề đồng thời.
Trong chế độ không đồng bộ, yêu cầu được chuyển theo luồng tới nhân của hệ điều hành để hoàn thành nó trong khi luồng tiếp tục xử lý một công việc khác. Khi công việc của nhân được thực hiện, nó báo hiệu cho luồng sau đó luồng nhận tín hiệu và ngắt công việc hiện tại và xử lý I / O công việc khi cần thiết.
Để đạt được sự đồng thời, kênh này cung cấp hai cách tiếp cận bao gồm một cách tiếp cận là trả về java.util.concurrent.Future object và khác là Truyền cho hoạt động một đối tượng kiểu java.nio.channels.CompletionHandler.
Chúng tôi sẽ hiểu cả hai cách tiếp cận với sự trợ giúp của từng ví dụ một.
Future Object - Trong trường hợp này của Giao diện Tương lai được trả về từ kênh. Trong giao diện Tương lai có get() phương thức trả về trạng thái hoạt động được xử lý không đồng bộ trên cơ sở đó có thể quyết định việc thực thi thêm tác vụ khác. Chúng tôi cũng có thể kiểm tra xem tác vụ đã hoàn thành hay chưa bằng cách gọi nó isDone phương pháp.
Thí dụ
Ví dụ sau đây cho thấy cách sử dụng đối tượng Tương lai và tác vụ không đồng bộ.
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();
}
}
Đầu ra
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 -
Cách tiếp cận này khá đơn giản vì trong cách này, chúng tôi sử dụng giao diện CompletionHandler và ghi đè hai phương pháp của nó, một là completed() phương thức được gọi khi thao tác I / O hoàn tất thành công và phương thức khác là failed() Phương thức này được gọi nếu các hoạt động I / O không thành công. Trong đó một trình xử lý được tạo ra để sử dụng kết quả của một hoạt động I / O không đồng bộ khi một tác vụ được hoàn thành thì chỉ trình xử lý có các chức năng được thực thi.
Thí dụ
Ví dụ sau đây cho thấy cách sử dụng CompletionHandler để tác vụ không đồng bộ.
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();
}
}
Đầu ra
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.