JavaRush /Blogue Java /Random-PT /Lendo no teclado - “leitores”

Lendo no teclado - “leitores”

Publicado no grupo Random-PT
Olá! Em palestras e tarefas, aprendemos como enviar dados para o console e vice-versa - ler dados do teclado. Leitura do teclado - “leitores” - 1Você até aprendeu a usar uma construção complexa para isso:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Mas ainda não respondemos a nenhuma pergunta.

Como isso funciona?

Na verdade, na maioria das vezes, qualquer programa não existe por si só. Ele pode se comunicar com outros programas, sistemas, Internet, etc. Pela palavra “comunicar” queremos dizer antes de tudo “trocar dados”. Ou seja, receba alguns dados de fora e, ao contrário, envie seus próprios dados para algum lugar. Existem muitos exemplos de troca de dados entre programas, mesmo na vida cotidiana. Assim, em muitos sites, em vez de se registrar, você pode fazer login usando sua conta do Facebook ou Twitter. Nessa situação, dois programas, digamos, o Twitter e o site onde você está tentando se cadastrar, trocam os dados necessários entre si, após o que você vê o resultado final - autorização bem-sucedida. O termo “ fluxo ” é frequentemente usado para descrever o processo de troca de dados na programação . De onde veio esse nome? “Fluxo” está mais associado a um rio ou riacho do que a uma programação. Na verdade, isso não é sem razão :) Um fluxo é, em essência, um dado em movimento. Ou seja, na programação não é a água que “flui” ao longo do riacho, mas sim os dados na forma de bytes e caracteres. A partir de um fluxo de dados, podemos receber dados em partes e fazer algo com eles. Novamente, vamos usar a analogia da “água fluindo”: você pode retirar água de um rio para preparar sopa, apagar um incêndio ou regar flores. Usando fluxos, você pode trabalhar com qualquer fonte de dados: a Internet, o sistema de arquivos do seu computador ou qualquer outra coisa - não importa. Streams são uma ferramenta universal. Eles permitem que o programa receba dados de qualquer lugar (fluxos de entrada) e os envie para qualquer lugar (fluxos de saída). A tarefa deles é a mesma: coletar dados de um lugar e enviá-los para outro. Os fluxos são divididos em dois tipos:
  1. Fluxo de entrada ( Input ) - usado para receber dados
  2. Fluxo de saída ( Saída ) - para envio de dados.
O fluxo de dados de entrada em Java é implementado na classe InputStreame o fluxo de dados de saída na classe OutputStream. Mas existe outra maneira de dividir os tópicos. Eles são divididos não apenas em entrada e saída, mas também em byte e caractere . Aqui o significado é claro sem explicação: um fluxo de bytes transmite informações na forma de um conjunto de bytes e um fluxo de caracteres transmite informações na forma de um conjunto de caracteres. Nesta palestra entraremos em detalhes sobre fluxos de entrada. E anexarei informações sobre links de saída no final, e você mesmo poderá ler sobre isso :) Então, nosso código:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Você provavelmente pensou enquanto lia as palestras que parecia bastante assustador? :) Mas isso é só até descobrirmos como essa coisa funciona. Vamos consertar isso agora! Vamos começar do fim. System.iné um objeto da classe InputStreamda qual falamos no início. Este é um fluxo de entrada e está vinculado ao dispositivo de entrada do sistema - o teclado. A propósito, você o conhece indiretamente. Afinal, você costuma usar o “colega” dele em seu trabalho - System.out! System.out- este é um fluxo de saída de dados do sistema , é usado para saída para o console no mesmo método System.out.println()que você usa constantemente :) System.out- um fluxo para enviar dados para o console e System.in- para receber dados do teclado. É simples :) Além disso: para ler dados do teclado, podemos prescindir desta grande construção e simplesmente escrever: System.in.read();
public class Main {

   public static void main(String[] args) throws IOException {

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
Na classe InputStream(e System.in, deixe-me lembrá-lo, é um objeto da classe InputStream) existe um método read()que permite a leitura de dados. Um problema: ele lê bytes e não caracteres . Vamos tentar ler a letra russa “Ya” no teclado. Saída do console:
Я
208
175
10
As letras russas ocupam 2 bytes na memória do computador (ao contrário das letras inglesas, que ocupam apenas 1). Neste caso, foram lidos 3 bytes do stream: os dois primeiros representam a nossa letra “I”, e o outro é a quebra de linha (Enter). Portanto, a opção de usar “nu” System.innão nos convém. Humanos (com raras exceções!) não conseguem ler bytes. É aqui que a próxima aula vem em nosso auxílio - InputStreamReader! Vamos descobrir que tipo de animal é esse.
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
Passamos o fluxo System.inpara o InputStreamReader. Em geral, se você traduzir seu nome para o russo, tudo parece óbvio - “leitor de fluxos de entrada”. Na verdade, é exatamente para isso que serve! Criamos um objeto de classe InputStreamReadere passamos a ele um fluxo de entrada do qual ele deve ler os dados. Nesse caso...
new InputStreamReader(System.in)
...nós dizemos: “você lerá os dados do fluxo de entrada do sistema (teclado)”. Mas esta não é a sua única função! InputStreamReadernão apenas recebe dados do fluxo. Ele também converte fluxos de bytes em fluxos de caracteres . Em outras palavras, você não precisa mais se preocupar em traduzir os dados lidos da linguagem “computador” para a linguagem “humana” - InputStreamReaderele fará tudo por você. InputStreamReader, é claro, pode ler dados não apenas do console, mas também de outros lugares. Por exemplo, do arquivo:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

   public static void main(String[] args) throws IOException {
       InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("C:\\Users\\username\\Desktop\\testFile.txt"));
   }
}
Aqui criamos um fluxo de dados de entrada FileInputStream(esta é uma das variedades InputStream), passamos o caminho do arquivo para ele e passamos o próprio fluxo InputStreamReader'y. Agora ele poderá ler os dados deste arquivo, se o arquivo neste caminho existir, é claro. Para ler dados (não importa de onde, no console, em um arquivo ou em qualquer outro lugar), a classe InputStreamReadertambém usa a extensão read(). Qual é a diferença entre System.in.read()e InputStreamReader.read()? Vamos tentar contar a mesma letra “I” usando InputStreamReader. Deixe-me lembrá-lo, foi isso que pensei System.in.read():
Я
208
175
10
Como ele pode fazer o mesmo trabalho InputStreamReader?
public class Main {

   public static void main(String[] args) throws IOException {

       InputStreamReader reader = new InputStreamReader(System.in);
       while (true) {
           int x = reader.read();
           System.out.println(x);
       }
   }
}
Saída do console:
Я
1071
10
A diferença é imediatamente visível. O último byte - para quebras de linha - permaneceu inalterado (o número 10), mas a letra lida “I” foi convertida em um único código “1071”. Isso é leitura por símbolos! Se de repente você não acredita que o código 1071 significa a letra “I”, é fácil verificar isso :)
import java.io.IOException;

public class Main {

   public static void main(String[] args) throws IOException {

       char x = 1071;
       System.out.println(x);
   }
}
Saída do console:

Я
Mas se InputStreamReaderé tão bom, por que você precisa de mais BufferedReader? InputStreamReaderpodemos ler dados e converter bytes em caracteres - o que mais precisamos? Por que outro leitor? :/ A resposta é muito simples – para maior produtividade e maior comodidade . Vamos começar com o desempenho. Ao ler dados, o BufferedReader usa uma área especial - um buffer, onde “adiciona” os caracteres lidos. Com isso, quando precisarmos desses caracteres no programa, eles serão retirados do buffer, e não diretamente da fonte de dados (teclado, arquivo, etc.), e isso economiza muitos recursos. Para entender como isso funciona, imagine, por exemplo, o trabalho de um entregador em uma grande empresa. O mensageiro fica no escritório e espera que os pacotes sejam entregues a ele. Cada vez que recebe um novo pacote, ele pode pegar a estrada imediatamente. Mas pode haver muitos pacotes durante o dia, e ele terá que se deslocar entre o escritório e os endereços todas as vezes. Em vez disso, o mensageiro colocou uma caixa no escritório onde todos poderiam colocar seus pacotes. Agora o entregador pode pegar a caixa com calma e ir até os endereços - vai economizar muito tempo, pois não terá que voltar sempre ao escritório. A caixa neste exemplo é precisamente o buffer e o escritório é a fonte de dados. É muito mais fácil para um mensageiro retirar uma carta de uma caixa comum ao entregá-la do que ir sempre ao escritório. Também economizará gás. É o mesmo em um programa - consome muito menos recursos extrair dados do buffer, em vez de acessar a fonte de dados todas as vezes. É por isso que BufferedReader+ InputStreamReaderfunciona mais rápido que apenas InputStreamReader. Resolvemos o desempenho, mas e a conveniência? A principal vantagem é que BufferedReaderele pode ler dados não apenas um caractere por vez (embora read()também possua um método para esse fim), mas também linhas inteiras! Isso é feito usando o readLine();
public class Main {

   public static void main(String[] args) throws IOException {

       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
       String s = reader.readLine();
       System.out.println("We read this line from the keyboard:");
       System.out.println(s);
   }
}
Saída do console:
JavaRush is the best site to learn Java!
Мы считали с клавиатуры эту строку:
JavaRush — лучший сайт для изучения Java!
Isto é especialmente útil ao ler uma grande quantidade de dados. Uma ou duas linhas de texto ainda podem ser lidas caractere por caractere. Mas contar “Guerra e Paz” uma letra de cada vez será um tanto problemático :) Agora o trabalho dos threads ficou muito mais claro para você. Para um estudo mais aprofundado, aqui está uma fonte adicional para você: Aqui você pode ler mais sobre fluxos de entrada e saída. Revisão de vídeo BufferedReaderde um de nossos alunos. Sim, sim, nossos alunos não apenas aprendem sozinhos, mas também gravam vídeos educativos para outras pessoas! Não se esqueça de curtir e se inscrever em nosso canal :)
É melhor se acostumar a ler a documentação oficial desde o início dos estudos. É a principal fonte de conhecimento sobre o idioma, e a maioria das respostas sempre pode ser encontrada lá.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION