"Olá, amigo! Hoje vamos nos familiarizar com fluxos de entrada/saída . Escolhemos este tópico alguns dias atrás, mas hoje vamos explorá-lo completamente. Os fluxos de entrada/saída são divididos em 4 categorias:"
1) Os fluxos são divididos de acordo com sua direção: fluxos de entrada e fluxos de saída
2) Os streams são divididos de acordo com seu tipo de dados: os que trabalham com bytes e os que trabalham com caracteres .
Aqui essas divisões são representadas em uma tabela:
Fluxo de entrada | fluxo de saída | |
---|---|---|
Funciona com bytes | InputStream | OutputStream |
Funciona com personagens | Leitor | Escritor |
Se um objeto implementa a interface InputStream , ele oferece suporte à capacidade de ler bytes sequencialmente.
Se um objeto implementa a interface OutputStream , ele oferece suporte à capacidade de gravar bytes sequencialmente.
Se um objeto implementa a interface Reader , ele suporta a capacidade de ler sequencialmente os caracteres (caracteres) dele.
Se um objeto implementa a interface Writer , ele oferece suporte à capacidade de gravar caracteres sequencialmente (caracteres) nele.

Um fluxo de saída é como uma impressora. Podemos enviar documentos para a impressora. Podemos enviar dados para um fluxo de saída.
De sua parte, um fluxo de entrada pode ser comparado a um scanner ou talvez a uma tomada elétrica. Com um scanner, podemos trazer documentos para o nosso computador. Ou podemos conectar a uma tomada elétrica e receber eletricidade dela. Podemos receber dados de um fluxo de entrada.
"Onde eles são usados?"
"Essas classes são usadas em todos os lugares em Java. Nosso conhecido System.in é uma variável estática InputStream nomeada na classe System ."
"Sério?! Então, todo esse tempo eu tenho usado um InputStream e nem percebi. System.out também é um stream?"
"Sim, System.out é uma variável estática PrintStream (um descendente de OutputStream ) na classe System."
"Quer dizer que sempre usei streams e nem sabia?"
"Sim, e isso apenas nos diz como esses fluxos são convenientes. Basta pegar um e usá-lo."
"Mas você não pode dizer isso sobre System.in. Constantemente tivemos que adicionar BufferedReader ou InputStreamReader a ele."
"Isso é verdade. Mas também havia razões para isso."
Existem muitos tipos de dados e muitas maneiras de trabalhar com eles. Assim, o número de classes de E/S padrão cresceu muito rapidamente, embora fizessem tudo quase da mesma maneira. Para evitar essa complexidade, os desenvolvedores Java usaram o princípio da abstração e dividiram as classes em muitas partes pequenas.
Mas você pode conectar essas partes de maneira coerente e obter uma funcionalidade muito complexa, se precisar. Veja este exemplo:
Emita uma string para o console |
|
Armazene o fluxo de saída do console em uma variável separada. Emita uma string para o fluxo. |
|
Crie uma matriz de bytes dinâmica (em expansão) na memória. Conecte-o a um novo fluxo de saída (objeto PrintStream). Emita uma string para o fluxo. |
|
"Honestamente, isso é como um conjunto de Lego. Só que não está claro para mim o que esse código está fazendo."
"Não se preocupe com isso por enquanto. Tudo no seu devido tempo."
Isto é o que eu quero que você lembre: se uma classe implementa a interface OutputStream, você pode gravar bytes nela. Quase exatamente como você envia dados para o console. O que ela faz com isso é problema dela. Com o nosso "kit Lego", não nos preocupamos com a finalidade de cada peça individual. Nós nos preocupamos com o fato de que a grande variedade de peças nos permite construir coisas tão legais.
"Ok. Então por onde começamos?"
GO TO FULL VERSION