¿Cuánto necesita saber sobre el canal de archivos asíncrono Java NIO? Eche un vistazo a este artículo.

En Java 7, AsynchronousFileChannel se agregó a Java NIO. Utilice AsynchronousFileChannel para leer y escribir datos de archivos de forma asincrónica.

Crear un AsynchronousFileChannel

Podemos crearlo usando el método estático open () proporcionado por AsynchronousFileChannel. El código de muestra es el siguiente:

Path path = Paths.get("data/test.xml");
AsynchronousFileChannel fileChannel =
    AsynchronousFileChannel.open(path, StandardOpenOption.READ);

El primer parámetro es una instancia de objeto de PATH, que apunta al archivo asociado con AsynchronousFileChannel.

El segundo parámetro es una o más opciones de operación, que determina qué operación realizará AsynchronousFileChannel en el archivo de destino. En el código de muestra, usamos StandardOpenOption.READ, que indica que vamos a leer el archivo de destino.

Leer datos

AsynchronousFileChannel proporciona dos formas de leer datos, ambas llamando a su propio método read (). A continuación se presentarán dos métodos.

La primera forma de usar Futrue para leer datos es llamar al método read () de AsynchronousFileChannel, que devuelve un objeto de tipo Future.

Future operation = fileChannelread(buffer, 0);

El primer parámetro es ByteBuffer. Los datos leídos de AsynchronousFileChannel se escriben primero en este ByteBuffer.

El segundo parámetro indica la posición inicial de lectura de datos del archivo.

Este método read () regresará inmediatamente, incluso si todo el proceso de lectura no ha finalizado por completo. Podemos usar operation.isDone () para verificar si la lectura está completa. La operación aquí es una instancia del tipo Future devuelta por el método read () anterior. El siguiente es un ejemplo de código detallado:

AsynchronousFileChannel fileChannel = 
    AsynchronousFileChannel.open(path, StandardOpenOption.READ);

ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;

Future<Integer> operation = fileChannel.read(buffer, position);

while(!operation.isDone());

buffer.flip();
byte[] data = new byte[buffer.limit()];
buffer.get(data);
System.out.println(new String(data));
buffer.clear();

El programa anterior primero crea un objeto AsynchronousFileChannel y luego llama a su método read () para devolver un Future. El método read () requiere dos parámetros, uno es ByteBuffer y el otro es la posición inicial de lectura del archivo. Luego, se llama al método isDone () en un bucle para verificar si el proceso de lectura está completo, y el método isDone () devolverá verdadero después de la finalización. Aunque esto permite que la CPU permanezca inactiva durante un tiempo, debemos esperar a que se complete la operación de lectura antes de continuar con los pasos siguientes.

Una vez que se completa la lectura, los datos se almacenan en ByteBuffer, y luego los datos se convierten en una cadena y se emiten.

Utilice CompletionHandler para leer datos

La segunda forma de leer datos es llamar a otro método read () sobrecargado de AsynchronousFileChannel, que requiere un CompletionHandler como parámetro. El siguiente es un ejemplo de código:

fileChannel.read(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {
    @Override
    public void completed(Integer result, ByteBuffer attachment) {
        System.out.println("result = " + result);

        attachment.flip();
        byte[] data = new byte[attachment.limit()];
        attachment.get(data);
        System.out.println(new String(data));
        attachment.clear();
    }

    @Override
    public void failed(Throwable exc, ByteBuffer attachment) {

    }
});

Una vez que se completa la operación de lectura, se llamará al método complete () de CompletionHandler. Su primer parámetro es un tipo Integer, que representa el número de bytes leídos. El segundo parámetro adjunto es de tipo ByteBuffer y se utiliza para almacenar los datos leídos. En realidad, es el tercer parámetro del método read (). En el ejemplo actual, usamos ByteBuffer para almacenar datos, pero también podemos usar otros tipos.

Cuando la lectura falla, se llamará al método failure () de CompletionHandler.

Escribir datos es como leer. También tenemos dos formas de escribir datos en AsynchronousFileChannel. Podemos llamar a sus dos métodos write () sobrecargados. Los presentaremos por separado a continuación.

Utilice Future para leer datos

AsynchronousFileChannel也可以异步写入数据。下面是一个完整的写入示例:

Path path = Paths.get("data/test-write.txt");
AsynchronousFileChannel fileChannel = 
    AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);

ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;

buffer.put("test data".getBytes());
buffer.flip();

Future<Integer> operation = fileChannel.write(buffer, position);
buffer.clear();

while(!operation.isDone());

System.out.println("Write done");

Primero cree una instancia de AsynchronousFileChannel en modo de escritura, luego cree un ByteBuffer y escriba algunos datos. Luego, escriba los datos en el archivo. Finalmente, verifique el futuro devuelto para ver si la escritura está completa.

Tenga en cuenta que el archivo de destino de escritura debe crearse de antemano; si no existe, el método writh () arrojará una excepción java.nio.file.NoSuchFileException.

Podemos solucionar este problema de las siguientes formas:

if(!Files.exists(path)){
    Files.createFile(path);
}

Utilice CompletionHandler para escribir datos

También podemos usar CompletionHandler en lugar de Future para escribir datos en AsynchronousFileChannel. De esta manera podemos saber más directamente si el proceso de escritura se completó. El siguiente es un programa de muestra:

Path path = Paths.get("data/test-write.txt");
if(!Files.exists(path)){
    Files.createFile(path);
}
AsynchronousFileChannel fileChannel = 
    AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);

ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;

buffer.put("test data".getBytes());
buffer.flip();

fileChannel.write(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {

    @Override
    public void completed(Integer result, ByteBuffer attachment) {
        System.out.println("bytes written: " + result);
    }

    @Override
    public void failed(Throwable exc, ByteBuffer attachment) {
        System.out.println("Write failed");
        exc.printStackTrace();
    }
});

Cuando se complete el procedimiento de escritura, se llamará al método complete () del CompletionHandler, por el contrario, si falla la escritura, se llamará al método failed ().

Preste atención a cómo se utiliza el adjunto de parámetros del método CompletionHandler.

Al final

Responda a los datos mediante un mensaje privado para recibir un resumen de las preguntas de la entrevista de Java de un fabricante importante + manual de Alibaba Taishan + una guía de aprendizaje para los puntos de conocimiento + un resumen de los puntos de conocimiento básicos de Java en un documento pdf de 300 páginas.

El contenido de estos materiales son todos los puntos de conocimiento que el entrevistador debe preguntar durante la entrevista. El capítulo incluye muchos puntos de conocimiento, incluidos conocimientos básicos, colecciones de Java, JVM, concurrencia multiproceso, principios de primavera, microservicios, Netty y RPC, Kafka , Diario, patrón de diseño, algoritmo Java, base de datos, Zookeeper, caché distribuida, estructura de datos, etc. expediente

Supongo que te gusta

Origin blog.csdn.net/weixin_46577306/article/details/107825583
Recomendado
Clasificación