Quais as características do NIO (Nova Entrada/Saída) que você conhece?
sobes.tech IA
Resposta da IA
A NIO fornece entrada/saída não bloqueante baseada em canais e buffers. Características principais:
-
Canais: São conexões abertas a entidades capazes de realizar operações de E/S (ficheiro, socket). Ao contrário dos fluxos, os canais podem realizar tanto leitura como escrita.
-
Buffers: São blocos de memória fixos usados para interagir com os dados dos canais. Os dados do canal são escritos no buffer e depois processados. Ou os dados do programa são escritos no buffer e depois no canal. Os buffers permitem uma gestão de memória mais eficiente.
-
Selectores: Permitem que um thread manipule operações de E/S em múltiplos canais. É uma característica chave para implementar E/S não bloqueante, pois o thread pode aguardar que vários canais estejam prontos para operações (leitura ou escrita).
-
E/S não bloqueante: Um thread que realiza uma operação de leitura ou escrita através de um canal não fica bloqueado até a operação terminar. Em vez disso, pode realizar outras tarefas enquanto os dados ficam disponíveis ou o buffer fica pronto para escrita. A prontidão do canal para a operação é verificada através do selector.
-
MappedByteBuffer: Buffer que mapeia diretamente um ficheiro na memória do processo. Isto pode aumentar significativamente o desempenho para ficheiros grandes, evitando a cópia de dados do núcleo para o espaço do utilizador.
-
E/S Scatter/Gather: Permite ler dados de um canal para vários buffers (scatter) ou escrever dados de vários buffers para um único canal (gather) numa única operação.
Exemplo de uso do Selector:
// Exemplo de registo de um canal no selector para operação de leitura
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false); // Coloca o canal em modo não bloqueante
Selector selector = Selector.open();
channel.register(selector, SelectionKey.OP_READ); // Regista o canal para monitorizar a prontidão para leitura
Exemplo de uso de MappedByteBuffer:
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
// Abrir ficheiro e obter canal
// RandomAccessFile raf = new RandomAccessFile("large_file.txt", "rw");
// FileChannel fileChannel = raf.getChannel();
// Mapear ficheiro na memória
// MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, fileChannel.size());
// Trabalhar com o buffer
// byte b = buffer.get(); // Ler um byte
// buffer.put(0, (byte) 65); // Escrever um byte