E / S sem bloqueio (Java) - Non-blocking I/O (Java)

java.nio (NIO significa E / S sem bloqueio) é uma coleção de APIs da linguagem de programação Java que oferece recursos para operações intensivas de E / S. Ele foi introduzido com a versão J2SE 1.4 de Java da Sun Microsystems para complementar um I / O padrão existente. NIO foi desenvolvido sob o Java Community Process como JSR 51. Uma extensão para NIO que oferece uma nova API de sistema de arquivos, chamada NIO.2, foi lançada com Java SE 7 ("Dolphin").

Recursos e organização

As APIs do NIO foram projetadas para fornecer acesso às operações de E / S de baixo nível de sistemas operacionais modernos. Embora as APIs sejam elas mesmas de nível relativamente alto, a intenção é facilitar uma implementação que possa usar diretamente as operações mais eficientes da plataforma subjacente.

As APIs Java NIO são fornecidas no java.niopacote e seus subpacotes. A documentação da Oracle identifica esses recursos.

Buffers NIO

A transferência de dados NIO é baseada em buffers ( java.nio.Buffere classes relacionadas). Essas classes representam uma extensão contígua de memória, junto com um pequeno número de operações de transferência de dados. Embora teoricamente essas sejam estruturas de dados de propósito geral, a implementação pode selecionar memória para alinhamento ou características de paginação, que de outra forma não são acessíveis em Java. Normalmente, isso seria usado para permitir que o conteúdo do buffer ocupasse a mesma memória física usada pelo sistema operacional subjacente para suas operações de E / S nativas, permitindo assim o mecanismo de transferência mais direto e eliminando a necessidade de qualquer cópia adicional. Na maioria dos sistemas operacionais, desde que a área específica da memória tenha as propriedades corretas, a transferência pode ocorrer sem o uso da CPU. O buffer NIO é intencionalmente limitado em recursos para oferecer suporte a esses objetivos.

Existem classes de buffer para todos os tipos primitivos de Java, exceto boolean, que podem compartilhar memória com buffers de byte e permitir a interpretação arbitrária dos bytes subjacentes.

Uso

Os buffers NIO mantêm vários indicadores que determinam a função de seus métodos de acesso. A implementação do buffer NIO contém um rico conjunto de métodos para modificar esses ponteiros:

  • O flip()método, em vez de executar uma função "inverter" ou paginação no sentido canônico, move o ponteiro de posição para a origem da matriz subjacente (se houver) e o ponteiro de limite para a posição anterior do ponteiro de posição .
  • Três get()métodos são fornecidos para transferir dados de um buffer NIO. A implementação em massa, em vez de executar uma "obtenção" no sentido tradicional, "coloca" os dados em um array especificado. O argumento "deslocamento" fornecido para este método não se refere ao deslocamento de dentro do buffer do qual ler, nem um deslocamento do ponteiro de posição , mas sim o deslocamento de 0 dentro da matriz de destino.
  • A menos que usando os métodos absoluto get()e put(), qualquer get()ou put()é conduzido a partir do indicador de posição . Caso seja necessário ler de uma posição diferente dentro da matriz subjacente, embora não ajuste a posição de escrita , os métodos mark()e reset()foram fornecidos.
  • O mark()método armazena efetivamente a posição do ponteiro de posição , definindo o ponteiro de marca para a posição do ponteiro de posição . O reset()método faz com que o ponteiro de posição se mova para a posição do ponteiro de marca .
  • Após a invocação do clear()método ou do flip()método, o ponteiro de marca é descartado.
  • O clear()método não garante o zeramento do buffer, mas retorna o ponteiro de limite para o limite superior da matriz subjacente e o ponteiro de posição para zero.
  • put()e as get()operações para buffers NIO não são thread-safe.
  • Você só pode map()um java.nio.MappedByteBufferde uma java.nio.channels.FileChannelaté Integer.MAX_VALUEno tamanho (2GiB); regiões além desse limite podem ser acessadas usando um deslocamento maior que zero.

Canais

Os canais ( classes que implementam a interface java.nio.channels.Channel) são projetados para fornecer transferências de dados em massa de e para os buffers NIO. Este é um mecanismo de transferência de dados de nível inferior que existe em paralelo com as classes da biblioteca de E / S de nível superior (pacotes java.ioe java.net). Uma implementação de canal pode ser obtido a partir de uma classe de transferência de dados de alto nível, tais como java.io.File, java.net.ServerSocket, ou java.net.Socket, e vice-versa. Os canais são análogos aos " descritores de arquivo " encontrados em sistemas operacionais do tipo Unix.

Os canais de arquivo ( java.nio.channels.FileChannel) podem usar buffers arbitrários, mas também podem estabelecer um buffer mapeado diretamente para o conteúdo do arquivo usando um arquivo mapeado na memória . Eles também podem interagir com os bloqueios do sistema de arquivos . Da mesma forma, os canais de soquete ( java.nio.channels.SocketChannele java.nio.channels.ServerSocketChannel) permitem a transferência de dados entre soquetes e buffers NIO.

FileChannelpode ser usado para fazer uma cópia de arquivo, o que é potencialmente muito mais eficiente do que usar leitura / gravação antiga com uma matriz de bytes. O código típico para isso é:

// Getting file channels
try(FileChannel in = FileChannel.open(source, StandardOpenOption.READ);
    FileChannel out = FileChannel.open(target, StandardOpenOption.WRITE)
){
    // JavaVM does its best to do this as native I/O operations.
    in.transferTo(0, in.size(), out);
}

Seletores

Um seletor ( java.nio.channels.Selectore subclasses) fornece um mecanismo para aguardar canais e reconhecer quando um ou mais se tornam disponíveis para transferência de dados. Quando vários canais são registrados com o seletor, ele permite o bloqueio do fluxo do programa até que pelo menos um canal esteja pronto para uso ou até que ocorra uma condição de interrupção.

Embora esse comportamento de multiplexação possa ser implementado com threads, o seletor pode fornecer uma implementação significativamente mais eficiente usando construções de sistema operacional de nível inferior. Um sistema operacional compatível com POSIX , por exemplo, teria representações diretas desses conceitos, select () . Uma aplicação notável desse design seria o paradigma comum em software de servidor, que envolve a espera simultânea de respostas em várias sessões.

Conjuntos de caracteres

Em Java, um conjunto de caracteres é um mapeamento entre caracteres Unicode (ou um subconjunto deles) e bytes. O java.nio.charsetpacote do NIO fornece recursos para identificar conjuntos de caracteres e fornecer algoritmos de codificação e decodificação para novos mapeamentos.

Recepção

É inesperado que um canal associado a um arquivo Java IO RandomAccess feche o descritor de arquivo em uma interrupção, enquanto o próprio método de leitura de RandomAccessFiles não faz isso.

JDK 7 e NIO.2

JDK 7 inclui um java.nio.filepacote que, com a Pathclasse (também novo para JDK 7), entre outras características, fornece capacidades estendidas para tarefas do sistema de arquivos, por exemplo, pode trabalhar com simbólicos / duro ligações e despejar grandes listas do diretório em buffers mais rapidamente do que o antigo Arquivo classe faz. O java.nio.filepacote e seu pacote relacionado java.nio.file.attribute, fornecem suporte abrangente para E / S de arquivos e para acessar o sistema de arquivos. Um provedor de sistema de arquivo zip também está disponível no JDK 7.

Referências

  1. ^ "Melhorias no Java I / O" . Documentação Oracle Java . Retirado em 8 de junho de 2017 .
  2. ^ "JSR 51: Novas APIs de E / S para a plataforma JavaTM" . O programa Java Community Process (SM) - JSRs: Java Specification Requests . Página visitada em 23/05/2009 .
  3. ^ "Este JSR será entregue como parte do Java SE 7" Dolphin "." "JSR 203: Mais novas APIs de E / S para a plataforma JavaTM (" NIO.2 ")" . O programa Java Community Process (SM) - JSRs: Java Specification Requests . 30/01/2006 . Página visitada em 23/05/2009 .
  4. ^ Não presuma que você sabe o que é melhor , Shawn Pearce, autor de Gerrit (Software) , 14/05/2010.

links externos