1. Conceitos básicos
O IO é o processo de copiar dados por memória principal e dispositivos externos (discos rígidos, terminais, redes etc.). O IO é a implementação funcional subjacente do sistema operacional, que é concluído por meio de instruções de E/S.
Todos os sistemas de tempo de execução do idioma fornecem ferramentas de alto nível para realizar E/S. (C's PrintfScanf, encapsulamento orientado a objetos de Java)
2. Revisão do Java Standard IO
A biblioteca de classe Java Standard IO é uma abstração de Orientado por objetos de IO. Com base na implementação subjacente dos métodos locais, não precisamos prestar atenção à implementação subjacente. InputStream/OutputStream: Transfira um byte por vez. Leitor/escritor: um personagem de cada vez.
3.nio Introdução
Nio é a abreviação de Javanewio, uma nova API fornecida no JDK1.4. As características que Sun afirma oficialmente são as seguintes:
Fornece suporte de cache (buffer) para todos os tipos primitivos.
Solução de codificação e decodificação do conjunto de caracteres.
Canal: uma nova abstração de E/S original.
Suporta interfaces de acesso a arquivos para arquivos de bloqueio e memória mapeados.
Fornece E/S de rede altamente escalável e não bloqueador e não escalável.
Este artigo aprenderá e introduzirá esses recursos.
4.Buffer & Chanel
Canal e buffer são Nio e são as duas abstrações mais básicas do tipo de dados.
Buffer:
É um bloco contínuo de memória.
É o local de trânsito para leitura ou escrita dos dados do NIO.
Canal:
A fonte de dados ou destino dos dados
Uma interface exclusiva para fornecer dados para buffers ou leitura de dados de buffer, objetos de buffer.
Suporte de E/S assíncrono
Exemplo 1: copyfile.java:
amostra do pacote; importar java.io.fileInputStream; importar java.io.fileOutputStream; importar java.nio.bytebuffer; importar java.nio.channels.FileChannel; public Class copyFile {public static void main (string [] args) args) Exception {string infile = c:/public static main (string [] args) throws); "C: //copy.txt"; // Obter fluxos de entrada e saída dos arquivos de origem e destino FileInputStream Fin = new FileInputStream (infile); FileOutputStream fout = new FileOutputStream (outfile); // obtendo os canais de entrada e saída FILECHANNEL FCIN = FINGEN.TENELEL (); Buffer bytebuffer = bytebuffer.Allocate (1024); enquanto (true) {// Método limpo redefine o buffer para que ele possa aceitar o buffer de dados de leitura.clear (); // Leia os dados do canal de entrada para o buffer int r = fcin.read (buffer); // o método de leitura retorna o número de bytes lido, que pode ser zero, se o canal atingiu o final do fluxo, retorno -1 se (r. LEIA dados recentemente para outro buffer de canal.flip (); // Escreva dados do canal de saída para o buffer fcout.write (buffer);}}}A estrutura interna do buffer é a seguinte (a figura a seguir é copiada das informações):
Figura 2: Estrutura interna do buffer
Um buffer controla principalmente o processo de leitura e escrita por três variáveis, limite e capacidade. O significado dessas três variáveis é mostrado na tabela a seguir:
parâmetro | Modo de escrita | Modo de leitura |
posição | O número de dados da unidade atualmente gravados. | A localização dos dados da unidade atual. |
limite | Representa o número máximo de unidades de dados e capacidade que podem ser gravadas é a mesma. | Representa o número máximo de unidades de dados que podem ser lidas, o que é consistente com a quantidade de dados da unidade gravados antes. |
capacidade | Capacidade de buffer | Capacidade de buffer |
Métodos de buffer comum:
flip (): converta o modo de gravação para o modo de leitura
Rewind (): Redefinir a posição para 0, geralmente usada para leitura repetida.
Limpar (): Limpe o buffer e prepare -se para ser escrito novamente (a posição se torna 0, o limite se torna capacidade).
compact (): copie dados não lidos para a cabeça do buffer.
Mark (), Reset (): Mark pode marcar uma posição, a redefinição pode ser redefinida para esta posição.
Tipos comuns de buffer: bytebuffer, mapedbytebuffer, charbuffer, duplobuffer, floatbuffer, intbuffer, longbuffer, shortbuffer.
Canais comuns: FileChannel, DataGramChannel (UDP), SocketchAnnel (TCP), ServerSocketchAnnel (TCP)
Um teste de desempenho simples foi realizado nesta máquina. Meu laptop realiza com moderação. (Consulte o anexo para o código específico. Veja o exemplo abaixo no pacote nio.sample.FileCopy) A seguir, os seguintes dados de referência:
Cenário 1: copie um arquivo de 370m
Cenário 2: três threads Copiarem ao mesmo tempo, cada thread copia um arquivo de 370m.
Cena | FileInputStream+ FileOutputStream | FileInputStream+ BufferInputStream+ FileOutputStream | BYTEBUFFER+ FileChannel | MappedByteBuffer +Filechannel |
Cena por um tempo (milissegundos) | 25155 | 17500 | 19000 | 16500 |
Cena 2 tempo (milissegundos) | 69000 | 67031 | 74031 | 71016 |
5.nio.charset
Codificação e decodificação de caracteres: O próprio bytecode é apenas alguns números, que são analisados corretamente no contexto correto. Ao armazenar dados no ByTeBuffer, você precisa considerar o método de codificação do conjunto de caracteres. Ao ler e exibir dados de bytebuffer, você envolve a decodificação do conjunto de caracteres.
Java.nio.charset fornece um conjunto de soluções para codificação e decodificação.
Tomando nossa solicitação HTTP mais comum como exemplo, a solicitação deve ser codificada corretamente ao solicitar. A resposta deve ser decodificada corretamente quando é obtida.
O código a seguir envia uma solicitação para o Baidu e obtém os resultados para a exibição. O exemplo demonstra o uso do charset.
Exemplo 2BaidUreader.java
pacote nio.readPage; importar java.nio.bytebuffer; importar java.nio.channels.socketchannel; importar java.nio.charset.charset; import java.net.inetsocketaddress; importeset; Canal de socketchannel; public void readhtmlContent () {try {inetSocketAddress socketaddress = new inetSocketAddress ("www.baidu.com", 80); // step1: abre o canal de conexão = socketchannel.open (socketaddress); // step1: send the Solictor Http/1.1 " +"/r/n/r/n ")); // etapa3: leia o buffer de bytebuffer de dados = bytebuffer.allocate (1024); // crie um buffer de 1024 byte while (canal. System.out.println (charset.decode (buffer)); // use o método charset.decode para converter bytes em string buffer.clear (); // buffer limpo}} catch (ioexception e) {system.err.println (e.tostring ();} {se (se (canal! e) {}}}} public static void main (string [] args) {new Baidureader (). readhtmlContent ();}}6. io não bloqueador
Em relação ao IO não bloqueador, entenderemos dos aspectos do que está bloqueando, o que não é bloqueador, o princípio não bloqueador e a API do núcleo assíncrono.
O que é bloqueio?
Um processo comum de comunicação de IO de rede é o seguinte:
Nesse processo de comunicação de rede, vamos entender o que é bloqueio:
Se a conexão não tiver chegado ao processo acima, aceitará bloquear, o programa terá que pendurar depois de executar aqui e a CPU executará outros threads.
Se os dados não estiverem prontos no processo acima, a leitura também será bloqueada.
Recursos da rede de bloqueio IO: múltiplas conexões com várias threads. Cada thread tem seu próprio espaço de pilha e ocupa algum tempo de CPU. Cada thread bloqueará quando encontrar um pronto para o outro. O resultado do bloqueio é que ele levará a um grande número de comutação de contexto de processo. E a maioria das mudanças de contexto de processo pode não ter sentido. Por exemplo, suponha que um thread ouça uma porta e haverá apenas algumas solicitações em um dia, mas a CPU precisa fazer constantemente as tentativas de troca de contexto para o thread e a maioria das extremidades de comutação no bloqueio.
O que não é bloqueador?
Aqui está uma metáfora:
Em um ônibus de A a B, há muitos pontos na estrada que podem sair. O motorista não sabe quais pontos sairão do ônibus. Como lidar com aqueles que precisam sair do ônibus melhor?
1. Durante o processo, o motorista pergunta regularmente a cada passageiro se ele chegou ao destino. Se alguém disser isso, o motorista para e o passageiro desce. (Semelhante ao bloqueio)
2. Todo mundo diz ao vendedor de ingressos seu destino e depois dorme. O motorista interage apenas com o vendedor de ingressos. Quando ele chegar a um certo ponto, o vendedor de ingressos notificará o passageiro para sair do ônibus. (Semelhante ao não bloqueio)
Obviamente, todos para chegar a um destino podem ser considerados um thread, e o motorista pode ser considerado uma CPU. No estilo de bloqueio, cada encadeamento precisa constantemente pesquisar e alternar o contexto para alcançar o resultado de encontrar o destino. No modo não bloqueador, todo passageiro (thread) está dormindo (dormindo) e só acorda quando o ambiente externo real está pronto. Esse despertar definitivamente não bloqueará.
O princípio do não bloqueio
Alterne todo o processo para pequenas tarefas e conclua -o através da colaboração entre as tarefas.
Um encadeamento dedicado lida com todos os eventos de IO e é responsável pela distribuição.
Mecanismo orientado a eventos: gatilhos quando um evento chega, em vez de monitorar eventos simultaneamente.
Comunicação de threads: os threads se comunicam através da espera, notificar e outros meios. Certifique -se de que cada interruptor de contexto faça sentido. Reduza a comutação desnecessária do processo.
A seguir, é apresentada a estrutura do IO assíncrono:
O reator é o papel metafórico acima do vendedor de ingressos. O fluxo de processamento de cada encadeamento é provavelmente ler dados, decodificar, calcular o processamento, codificar e enviar respostas.
API CORE ASÍNICO IO
Seletor
A classe principal de IO assíncrono, que pode detectar eventos em um ou mais canais e distribuir eventos.
Use um thread selecione para ouvir eventos em vários canais e acionar as respostas correspondentes com base nos drivers de evento. Não há necessidade de alocar um thread para cada canal.
SelectionKey
Contém a ligação do canal correspondente às informações de status do evento e do tempo.
Resumir
O exposto acima é o conteúdo inteiro deste artigo sobre ensaios básicos de conhecimento Java, espero que seja útil para todos. Amigos interessados podem continuar se referindo a outros tópicos relacionados neste site. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!