Streams permitem a leitura e escrita de dados para ficheiros, memória, rede, teclado, monitor, etc. São o mecanismo base que permite a interacção do nosso programa com elementos externos.
Antes de abordarmos mais o conceito de Streams em Java, vamos introduzir a classe mais importante que existe no package java.io, a classe File.
Esta classe representa um sistema de ficheiros que não está dependente da plataforma, por esse motivo é a classe que usamos sempre que pretendemos manipular um ficheiro, quer ele esteja no disco, quer seja apenas dado por um URL ou outro mecanismo qualquer. Mas por não estar associado a um sistema de ficheiros específicos, os objectos da classe File não representam um ficheiro e não permitem, entre outras coisas:
A classe File permite criar ficheiros, temporários ou não, criar directorias1), listar drives no nosso sistema e fornece acesso a algumas informações sobre os ficheiros. Estas informações estão também limitadas pelo facto de sistemas de ficheiros diferentes terem dados diferentes, por isso há algumas informações que podemos tomar como garantidas mas que não estão disponíveis2).
Uma stream não é mais que um canal no qual a informação circula em determinado sentido e que liga um produtor a um consumidor. Streams são um conceito genérico que abrange ficheiros em disco, sockets, dados em memória, etc. Não é restrito a apenas ficheiros, embora seja onde se verifica mais a sua utilização.
Em Java, as streams podem ser agrupadas em streams simples ou processadas se olharmos para a forma como actuam nos dados ou em streams binárias e de texto se olharmos para o tipo de dados com que lidam.
Desta forma, as streams simples são streams que não modificam nem processam qualquer dado que transportam. Estas são streams de mais nível mais baixo. As streams processadas tratam os dados que fornecem e dão-nos métodos para obter os dados processados.
Se considerarmos o tipo de dados, as streams binárias tratam apenas de dados em formato binário enquanto que as streams de texto tratam apenas os dados em formato de texto. Existem streams que permitem passar de binário para texto, se necessário.
Tipo de Armazenamento | Streams de texto | Streams binárias |
---|---|---|
Memória | CharArrayReader CharArrayWriter | ByteArrayInputStream ByteArrayOutputStream |
StringReader StringWriter | StringBufferInputStream | |
Pipe | PipedReader PipedWriter | PipedInputStream PipedOutputStream |
Ficheiro | FileReader FileWriter | FileInputStream FileOutputStream |
Processo | Streams de texto | Streams binárias |
---|---|---|
Utilização de um buffer | BufferedReader BufferedWriter | BufferedInputStream BufferedOutputStream |
Contabiliza o número de linhas | LineNumberReader | LineNumberInputStream |
Leitura antecipada | PushbackReader | PushbackInputStream |
Escrita formatada | PrintWriter | PrintStream |
Concatenação de streams | - | SequenceInputStream |
Conversão entre streams binárias e streams de texto | InputStreamReader OutputStreamWriter | - |
Conversão de dados | - | DataInputStream DataOutputStream |
Armazenamento de objectos | _ | ObjectInputStream ObjectOutputStream. Estas streams são referidas em maior detalhe na secção Serialização |
Classe | Objectivo |
---|---|
StreamTokenizer | Permite dividir um ficheiro de texto em palavras (tokens) de acordo com um conjunto de regras. |
CheckedInputStream | Permite verificar a integridade de uma stream de leitura através do cálculo de um valor de verificação (checksum). |
CheckedOutputStream | Permite garantir a integridade de uma stream de escrita através do cálculo de um valor de verificação (checksum). |
InflaterInputStream | Classe base para as classes de descompressão (ZipInputStream e GZIPInputStream). Classe base para as classes de compressão (ZipOutputStream e GZIPOutputStream). |
DeflaterOutputStream | |
ZipOutputStream/ZipInputStream | Classe que permite a compressão/descompressão de dados utilizando o formato Zip. |
GZIPOutputStream/GZIPInputStream | Classe que permite a compressão/descompressão de dados utilizando o formato GZIP (extensão .gz). |
As streams padrão são streams que existem em todas as aplicações Java, mesmo que o programador não as use, e que estão acessíveis através de variáveis da classe System: System.in, System.out e System.err.
Estas streams oferecem a possibilidade de se ler dados do teclado, System.in, de se escrever dados para o ecrã, System.out e de se escrever dados para a consola de erros, System.err3). Os seus tipos são, respectivamente, InputStream, PrintStream e PrintStream.
Apesar de poderem ser redirectionadas, estas são as 3 streams usadas para receber dados do teclado e para enviar dados para a consola em que o utilizador está a executar a aplicação.
Para um exemplo de utilização destas streams pode ver o tutorial Ler a partir do Teclado.