Nov 28, 2025

Como usar o CompletionHandler na E/S assíncrona Java NIO?

Deixe um recado

Ei! Como fornecedor NIO, tenho mergulhado profundamente no mundo da E/S assíncrona Java NIO e hoje estou feliz em compartilhar com vocês como usar CompletionHandler na E/S assíncrona Java NIO. É um conceito muito legal que pode realmente melhorar seu jogo de programação, especialmente quando se trata de operações de E/S de alto desempenho.

Primeiro, vamos entender do que se trata a E/S assíncrona Java NIO. Na E/S Java tradicional, as operações são bloqueadas. Isso significa que quando você está executando uma operação de E/S, como ler um arquivo ou obter dados de um soquete de rede, seu programa precisa esperar até que a operação seja concluída antes de poder passar para a próxima tarefa. Isso pode ser uma verdadeira chatice, especialmente em um aplicativo de alto tráfego onde você não quer que seu programa fique parado esperando.

A E/S assíncrona Java NIO, por outro lado, permite que seu programa continue realizando outras tarefas enquanto a operação de E/S está em andamento. Ele usa uma abordagem baseada em retorno de chamada ou futura para notificar seu programa quando a operação for concluída. E é aí que entra o CompletionHandler.

Um CompletionHandler é uma interface em Java NIO que define dois métodos:concluídoefracassado. OconcluídoO método é chamado quando a operação de E/S assíncrona é concluída com êxito e fornece acesso ao resultado da operação. OfracassadoO método é chamado se algo der errado durante a operação e fornece informações sobre o erro.

Vamos começar com um exemplo simples de uso do CompletionHandler para leitura assíncrona de arquivos.

importar java.nio.ByteBuffer; importar java.nio.channels.AsynchronousFileChannel; importar java.nio.channels.CompletionHandler; importar java.nio.file.Path; importar java.nio.file.Paths; importar java.nio.file.StandardOpenOption; classe pública AsyncFileReadExample { public static void main(String[] args) { Path path = Paths.get("test.txt"); tente (AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open (caminho, StandardOpenOption.READ)) { ByteBuffer buffer = ByteBuffer.allocate (1024); fileChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void concluído(resultado inteiro, anexo ByteBuffer) { System.out.println("Leitura " + resultado + " bytes"); buffer.flip(); byte[] dados = new byte[buffer.limit()]; buffer.get(dados); System.out.println(new String (dados)); } @Override public void falhou (Throwable exc, anexo ByteBuffer) { System.err.println("Falha na leitura: " + exc.getMessage()); // Realiza outras tarefas enquanto a operação de leitura está em andamento System.out.println("Doing other tasks..."); Thread.sleep(2000); } catch (Exceção e) { e.printStackTrace(); } } }

Neste exemplo, primeiro abrimos umCanal de arquivo assíncronopara leitura. Então alocamos umByteBufferpara armazenar os dados que vamos ler. Chamamos olerno canal do arquivo, passando no buffer, a posição para iniciar a leitura (neste caso, 0), um anexo (que pode ser qualquer objeto que você queira passar junto com a operação) e uma instância do nossoCompletionHandler.

Nio ET5 specificationsNio ET5 vs competitors

Oconcluídométodo noCompletionHandleré chamado quando a operação de leitura é bem-sucedida. Ele imprime o número de bytes lidos, inverte o buffer e depois imprime o conteúdo do buffer como uma string. OfracassadoO método é chamado se houver um erro durante a operação de leitura e imprime uma mensagem de erro.

Enquanto a operação de leitura está em andamento, nosso programa pode continuar realizando outras tarefas. Neste exemplo simples, apenas imprimimos uma mensagem e depois dormimos por alguns segundos.

Agora, vamos falar sobre o uso do CompletionHandler para E/S de rede. Suponha que você esteja construindo um aplicativo cliente-servidor e queira lidar com conexões de entrada de forma assíncrona.

importar java.io.IOException; importar java.net.InetSocketAddress; importar java.nio.ByteBuffer; importar java.nio.channels.AsynchronousServerSocketChannel; importar java.nio.channels.AsynchronousSocketChannel; importar java.nio.channels.CompletionHandler; classe pública AsyncServerExample { public static void main (String [] args) { try (AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open()) { serverSocketChannel.bind (new InetSocketAddress (8080)); System.out.println("Servidor iniciado na porta 8080"); serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() { @Override public void concluído(AsynchronousSocketChannel clientChannel, Void attachment) { serverSocketChannel.accept(null, this); System.out.println("Novo cliente conectado"); ByteBuffer buffer = ByteBuffer.allocate(1024); clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void concluído(resultado inteiro, anexo ByteBuffer) { if (resultado > 0) { attachment.flip(); byte[] data = new byte[attachment.limit()]; attachment.get(data); String message = new String(data); System.out.println("Recebido: " + mensagem); tentar { clientChannel.write(ByteBuffer.wrap(("Você enviou: " + message).getBytes())).get(); } catch (Exception e) { e.printStackTrace(); System.err.println("Falha na leitura: " + exc.getMessage()); try { clientChannel.close(); catch (IOException e) { e.printStackTrace(); // Mantém o servidor rodando Thread.sleep(Long.MAX_VALUE); } catch (Exceção e) { e.printStackTrace(); } } }

Neste exemplo de servidor, abrimos umAssíncronoServerSocketChannele vinculá-lo à porta 8080. Então chamamos oaceitarmétodo no canal de soquete do servidor, passando umCompletionHandler. Quando um novo cliente se conecta, oconcluídométodo doCompletionHandleré chamado. Dentro deste método, aceitamos outra conexão (para que o servidor possa lidar com vários clientes), imprimimos uma mensagem indicando que um novo cliente se conectou e então começamos a ler os dados do cliente.

Usamos outroCompletionHandlerpara a operação de leitura. Se a leitura for bem-sucedida, imprimimos a mensagem recebida e enviamos uma resposta ao cliente. Se houver algum erro, imprimimos uma mensagem de erro e fechamos o canal do cliente.

Uma das grandes vantagens de usar CompletionHandler em E/S assíncrona Java NIO é que ele permite que você lide com várias operações de E/S simultaneamente sem bloquear seu programa. Isso pode levar a aplicativos muito mais eficientes e responsivos, especialmente em cenários onde você tem um grande número de clientes ou transferências de dados de alto volume.

Se você gosta de carros elétricos, pode estar interessado noCarro elétrico Nio ET5. É um veículo elétrico elegante e de alto desempenho que combina estilo e tecnologia, assim como o CompletionHandler combina eficiência e flexibilidade em E/S assíncrona Java NIO.

Como fornecedor da NIO, conheço a importância de sistemas confiáveis ​​e de alto desempenho. Seja na indústria automotiva ou na programação de software, estamos sempre buscando maneiras de otimizar e melhorar. Se você estiver interessado em aprender mais sobre E/S assíncrona Java NIO ou tiver alguma necessidade relacionada aos nossos produtos e serviços, não hesite em entrar em contato. Estamos aqui para ajudá-lo a levar seus projetos para o próximo nível. Vamos conversar sobre como podemos trabalhar juntos para atender às suas necessidades.

Referências:

  • Documentação Java NIO
  • Vários tutoriais e blogs de programação online
Enviar inquérito