1. InputStreamReaderaula
Outro recurso interessante dos fluxos é que você pode combinar vários fluxos em cadeias . Um fluxo pode ler dados não apenas de sua fonte de dados interna, mas também de outro fluxo .
Este é um mecanismo muito poderoso em Java, que permite criar cenários complexos de leitura de dados conectando um fluxo a outro. Tal esquema se parece com isso:

Quando um programa lê dados de um fluxo de dados, o fluxo de dados, por sua vez, lê os dados de sua fonte de dados, que é outro fluxo de dados ou um arquivo, por exemplo.
Além do mais, cada fluxo de dados não apenas lê e distribui dados, mas também pode transformá-los ou realizar várias operações neles. Um bom exemplo desse "fluxo intermediário" é a InputStreamReaderclasse.
Já conhecemos uma classe chamada FileReader— é uma Readerque lê dados de um arquivo. E InputStreamReaderde onde obtém seus dados? Isso mesmo - de um arquivo InputStream.
Ao criar um InputStreamReaderobjeto, você precisa passar um InputStreamobjeto ou uma de suas classes descendentes. Exemplo:
String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);
A InputStreamReaderclasse tem todos os métodos que a Readerclasse tem e eles funcionam exatamente da mesma maneira.
A principal diferença entre a InputStreamReaderclasse e, digamos, FileReaderé de onde eles leem os dados. FileReaderlê dados de um arquivo (duh - é por isso que é chamado FileReader), mas InputStreamReaderlê dados de um arquivo InputStream.
Quando você lê um caractere de um FileReaderobjeto usando o read()método, ele, por sua vez, lê dois bytes do arquivo no disco e os retorna como chars.
Quando você lê um caractere de um InputStreamReaderobjeto usando o read()método, ele, por sua vez, lê dois bytes do FileInputStreamobjeto passado para ele, que por sua vez lê os dados do arquivo. O resultado é uma cadeia de chamadas para read()métodos.
2. BufferedReaderclasse
Outra classe interessante que você provavelmente usará muito é BufferedReader. Este também é um "fluxo intermediário" que lê dados de outro fluxo.
Como o próprio nome sugere, a BufferedReaderclasse é uma subclasse de Readere permite que você leia caracteres . Mas o mais interessante é que você também precisa passar para ela uma fonte de dados na forma de um stream a partir do qual os caracteres podem ser lidos , ou seja, um stream que herda a Readerclasse.
Qual é o ponto? Ao contrário de InputStreamReader, a BufferedReaderclasse não converte bytes em caracteres: ela não converte absolutamente nada. Em vez disso, ele armazena os dados em buffer .

Quando um programa lê um único caractere de um BufferedReaderobjeto, o objeto lê uma grande variedade de caracteres de seu fluxo de origem de uma só vez. E os armazena internamente.
Quando o próximo caractere é lido do BufferedReaderobjeto, ele simplesmente pega o próximo caractere de sua matriz de buffer interno e o retorna sem acessar a fonte de dados. Somente quando todos os caracteres no buffer são usados, ele lê em outra grande matriz de caracteres.
A BufferedReaderclasse também tem um método muito útil — String readLine(), que permite ler sequências inteiras de dados do fluxo de origem de uma só vez. Você pode usar esse método para, digamos, ler um arquivo e exibir seu conteúdo na tela linha por linha. Exemplo:
Escrevemos especificamente um código compacto para ilustrar como isso pode ser conveniente. Esse código também poderia ser escrito com um pouco mais de detalhes.
|
Crie um FileReaderobjeto. A fonte de dados é um arquivo. Crie um BufferedReaderobjeto. A fonte de dados é um arquivo FileReader. Enquanto ainda houver dados no leitor Leia uma linha Exiba a linha |
Se você encadear vários fluxos, o close()método só precisará ser chamado em um deles. Esse fluxo chamará o método em sua fonte de dados e assim por diante, até close()ser chamado no fluxo de dados final.
3. Lendo no console
E mais um fato interessante: a Scannerclasse nada mais é do que um fluxo de entrada intermediário que lê dados de System.in, que também é um fluxo de dados.
Aqui estão duas maneiras de ler uma linha do console:
| classe do scanner | Classes BufferedReader e BufferedWriter |
|---|---|
|
|
Nosso amigo nada mais é do que uma variável estática da classe. É um cujo nome é .System.ininSystemInputStreamin
Assim, quase desde o início de seus estudos de Java no CodeGym, você trabalhou com fluxos de dados e construiu cadeias a partir deles. Mas agora você fará isso de forma mais consciente.
GO TO FULL VERSION