0% acharam este documento útil (0 voto)
2 visualizações38 páginas

Java Streams

O documento aborda o uso de Java para manipulação de arquivos e fluxos de entrada e saída, detalhando classes como FileInputStream, InputStreamReader, BufferedReader, FileWriter e BufferedWriter. Ele também discute a importância do tratamento de exceções e apresenta exemplos práticos, incluindo a cópia de arquivos e a implementação de um chat simples usando sockets. Além disso, menciona conceitos de design como o padrão Decorator e a diferença entre Streams e Readers.

Enviado por

gsouza590
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
2 visualizações38 páginas

Java Streams

O documento aborda o uso de Java para manipulação de arquivos e fluxos de entrada e saída, detalhando classes como FileInputStream, InputStreamReader, BufferedReader, FileWriter e BufferedWriter. Ele também discute a importância do tratamento de exceções e apresenta exemplos práticos, incluindo a cópia de arquivos e a implementação de um chat simples usando sockets. Além disso, menciona conceitos de design como o padrão Decorator e a diferença entre Streams e Readers.

Enviado por

gsouza590
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

Java e java.

io: Streams, Reader


e Writers
Resumo

1. Fluxos de Entrada e Saída


Detalhes: FileInputStream é usado para criar um fluxo de entrada a partir de um
arquivo. Este é um exemplo básico de como ler bytes de um arquivo.
Exemplo:

try {
FileInputStream fis = new FileInputStream("[Link]
t");
int data;
while ((data = [Link]()) != -1) {
[Link]((char) data);
}
[Link]();
} catch (IOException e) {
[Link]();
}

2. Transformação de Dados
Detalhes: InputStreamReader converte um fluxo de bytes ( InputStream ) em
caracteres. O BufferedReader permite ler esses caracteres em forma de strings.
Exemplo:

try {
FileInputStream fis = new FileInputStream("[Link]

Java e [Link]: Streams, Reader e Writers 1


t");
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = [Link]()) != null) {
[Link](line);
}
[Link]();
} catch (IOException e) {
[Link]();
}

3. Gerenciamento de Arquivos
Detalhes: FileWriter e BufferedWriter são usados para escrever texto em
arquivos, com BufferedWriter proporcionando eficiência na escrita.
Exemplo:

try {
FileWriter fw = new FileWriter("[Link]");
BufferedWriter bw = new BufferedWriter(fw);
[Link]("Exemplo de texto.");
[Link]();
[Link]();
} catch (IOException e) {
[Link]();
}

4. Práticas com Exceções


Detalhes: Tratamento de exceções, como FileNotFoundException e IOException ,é
crucial para lidar com erros de I/O.
Exemplo:

try {
FileInputStream fis = new FileInputStream("arquivo_ine

Java e [Link]: Streams, Reader e Writers 2


[Link]");
} catch (FileNotFoundException e) {
[Link]("Arquivo não encontrado.");
} catch (IOException e) {
[Link]("Erro de I/O.");
}

5. Uso Avançado de Streams e Readers


Detalhes: A classe Scanner é usada para ler dados de arquivos de forma mais
fácil, especialmente útil para ler arquivos CSV.
Exemplo:

try {
Scanner scanner = new Scanner(new File("[Link]"));
while ([Link]()) {
String line = [Link]();
[Link](line);
}
[Link]();
} catch (FileNotFoundException e) {
[Link]();
}

6. Decorador e Padrões de Projeto


Detalhes: O padrão Decorator é utilizado em [Link], onde BufferedReader

decora FileReader para adicionar funcionalidade.


Exemplo:

FileReader fr = new FileReader("[Link]");


BufferedReader br = new BufferedReader(fr);
String line;
while ((line = [Link]()) != null) {
[Link](line);

Java e [Link]: Streams, Reader e Writers 3


}
[Link]();

7. Formatação de Saída
Detalhes: Uso de [Link]() para produzir saídas formatadas de strings.
Exemplo:

String name = "Mundo";


String message = [Link]("Olá, %s!", name);
[Link](message);

8. Java Network e Sockets


Detalhes: Sockets são usados para comunicação de rede. Socket permite
enviar e receber dados usando InputStream e OutputStream .
Exemplo:

try {
Socket socket = new Socket("[Link]", 80);
InputStream is = [Link]();
OutputStream os = [Link]();
// Envio e recepção de dados aqui.
[Link]();
} catch (IOException e) {
[Link]();
}

9. Propriedades e Configurações
Detalhes: A classe Properties é usada para gerenciar configurações externas.
Exemplo:

Properties props = new Properties();


[Link]("username", "usuario");
[Link]("password", "senha");

Java e [Link]: Streams, Reader e Writers 4


[Link]("Usuário: " + [Link]("userna
me"));
// Salvar e carregar propriedades com [Link]() e prop
[Link]()
``

### 10. **Exemplos Práticos e Exercícios**


**Detalhes**: Exercícios para praticar cada conceito.
**Exemplo**:
- Criar um programa que copie um arquivo usando `BufferedR
eader` e `BufferedWriter`.
- Implementar um chat simples usando sockets.

Essas explicações e exemplos devem fornecer uma base sólid


a para entender e aplicar os conceitos e classes de java.i
o em diferentes situações de programação.

Vamos resolver os dois exercícios propostos para aplicar e reforçar os


conceitos de [Link] que discutimos:

Exercício 1: Copiar um arquivo usando BufferedReader e


BufferedWriter
Este exercício consiste em ler o conteúdo de um arquivo e escrevê-lo em
outro arquivo, utilizando BufferedReader para ler e BufferedWriter para escrever.
Aqui está o código em Java para realizar esta tarefa:

import [Link].*;

public class FileCopyExample {


public static void main(String[] args) {
String sourceFile = "[Link]";
String destinationFile = "[Link]";

Java e [Link]: Streams, Reader e Writers 5


try (BufferedReader br = new BufferedReader(new Fi
leReader(sourceFile));
BufferedWriter bw = new BufferedWriter(new Fi
leWriter(destinationFile))) {

String line;
while ((line = [Link]()) != null) {
[Link](line);
[Link](); // Adiciona uma nova linha a
pós escrever a linha do arquivo original
}
} catch (IOException e) {
[Link]("An I/O Error Occurred: " +
[Link]());
}
}
}

Neste código:
BufferedReader é usado para ler cada linha do arquivo fonte [Link] .
BufferedWriter é usado para escrever cada linha lida no arquivo de destino
[Link] .

O método readLine() retorna null quando o fim do arquivo é alcançado.


newLine() é usado para garantir que cada linha do arquivo fonte seja
escrita em uma nova linha no arquivo de destino.
O uso de try-with-resources garante que tanto o BufferedReader quanto o
BufferedWriter sejam fechados automaticamente após o término da

operação, mesmo se uma exceção ocorrer.

Exercício 2: Implementar um chat simples usando sockets


Este exercício envolve a criação de uma comunicação simples entre cliente e
servidor usando sockets. Vamos criar duas classes: ChatServer e ChatClient .

[Link]

Java e [Link]: Streams, Reader e Writers 6


import [Link].*;
import [Link].*;

public class ChatServer {


public static void main(String[] args) {
[Link]("Servidor iniciado. Aguardando
conexão...");
try (ServerSocket serverSocket = new ServerSocket
(5000);
Socket clientSocket = [Link]();
BufferedReader in = new BufferedReader(new In
putStreamReader([Link]()));
PrintWriter out = new PrintWriter(clientSocke
[Link](), true)) {

[Link]("Cliente conectado: " + cli


[Link]().getHostAddress());
String inputLine;
while ((inputLine = [Link]()) != null) {
[Link]("Cliente diz: " + input
Line);
[Link]("Eco: " + inputLine);
}
} catch (IOException e) {
[Link]("Erro no servidor: " + [Link]
tMessage());
}
}
}

[Link]
import [Link].*;
import [Link].*;

Java e [Link]: Streams, Reader e Writers 7


import [Link];

public class ChatClient {


public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 500
0);
BufferedReader in = new BufferedReader(new In
putStreamReader([Link]()));
PrintWriter out = new PrintWriter([Link]
utputStream(), true);
Scanner scanner = new Scanner([Link])) {

String userInput;
while (true) {
[Link]("Digite uma mensagem: ");
userInput = [Link]();
if ("exit".equalsIgnoreCase(userInput)) {
break;
}
[Link](userInput);
[Link]("Servidor responde: " +
[Link]());
}
} catch (IOException e) {
[Link]("Erro no cliente: " + [Link]
Message());
}
}
}

Nestes códigos:
O ChatServer escuta na porta 5000 e aceita conexões. Ele lê linhas de
entrada do cliente, ecoa cada linha recebida de volta para o cliente.
O ChatClient se conecta ao servidor local na porta 5000, envia mensagens
digitadas pelo usuário e recebe respostas do servidor.

Java e [Link]: Streams, Reader e Writers 8


Ambos utilizam try-with-resources para garantir que todos os recursos
sejam fechados corretamente ao final da execução.
Estes exemplos abordam as operações básicas de I/O com arquivos e rede
em Java, proporcionando uma boa prática com as APIs de [Link] e [Link].

Leitura com [Link]

Estabelecendo a entrada
Vamos estabelecer um fluxo de entrada com o Arquivo .
Nosso objetivo é estabelecer um fluxo de entrada com um arquivo. Já que em
Java trabalhamos com a língua inglesa, precisamos traduzir certos termos,
arquivo por exemplo, é "file", entrada é "input", e fluxo é "stream", resultado em
um FileInputStream.

Existe o construtor que recebe um File. E um outro construtor String name,


representando o nome do arquivo com o qual desejamos trabalhar.
Como sabemos, há dois tipos de exceção, checked e unchecked, o [Link] está
repleto de exceções checked .
Java não é capaz de garantir que o desenvolvedor realmente inseriu o arquivo na
raiz do projeto, por isso, o código está passível de falhas. Precisamos alertar
sobre esta falha, e o modo pelo qual fazemos isso é a exceção do tipo checked.

Java e [Link]: Streams, Reader e Writers 9


Utilizando a variável fis, podemos utilizar uma série de métodos, dentre eles, está
o read(). O seu retorno é do tipo int, ou seja, um número. Isso indica que ele é
capaz de ler os bytes, o que não é interessante para nós, não queremos as
informações de bytes e binários, mas sim os caracteres.

Entretanto, nos parece que o FileInputStream não é capaz de realizar isto que
desejamos. Para isso, teremos de utilizar uma outra classe.
Há uma classe capaz de transformar um int em caracteres, que se chama
InputStreamReader. A ideia é que ela é capaz de ler um FileInputStream.

Java e [Link]: Streams, Reader e Writers 10


A variável isr nos permite utilizar uma outra variedade de métodos, além do
método read() citado acima, há um segundo, que recebe como parâmetro um
array de caracteres. Ele também nos retorna um int, entretanto, neste caso ele
corresponde ao número de caracteres que foram lidos.
Neste caso, conseguimos transformar bits e bytes em caracteres, mas ainda não
é a melhor solução para nosso problema.
A ideia é que sejamos capazes de ler as linhas inteiras do arquivo de texto, para
isso, temos que "guardar" cada um dos caracteres, até sermos capazes de
completar uma linha, e assim por diante.
Para esta tarefa, há o que chamamos de BufferedReader

Primeiro, criamos o fluxo concreto com o arquivo, mas ainda binário, em


seguida, conseguimos transformá-los em caracteres, mas apenas a

Java e [Link]: Streams, Reader e Writers 11


contabilização, por fim, com o BufferedReader, podemos utilizar o método
readLine(), que nos permite ler linha a linha.
Ao trabalharmos com [Link] é necessário dominarmos dois tipos principais de
exceção, a primeira é a FileNotFoundException, que já vimos, e a segunda é a
IOException.
O compilador indica que estabelecemos uma entrada em BufferedReader, mas
não uma saída, assim, fecharemos com o [Link](). Isso faz com que tanto o
FileInputStream quanto o InputStreamReader sejam fechados automaticamente.
Por isso não há necessidade de os fecharmos individualmente.

InputStream e Reader

Isso que fizemos é um padrão de projeto chamado decorator, ou seja, um objeto


está decorando a funcionalidade de outro, sucessivamente. Em geral, o [Link]
é repleto de padrões de projeto.
O método readLine() nos dá um retorno null quando não há mais nenhum
conteúdo, portanto, criaremos um while, indicando que, enquanto a linha não for
nula (null), teremos a impressão desta e leremos a próxima:

Java e [Link]: Streams, Reader e Writers 12


Dois conceitos que vemos muito presentes em nosso código, os termos Stream e
Reader. Eles existem tanto para entrada quanto saída, mas por enquanto
focaremos somente na entrada.
Primeiro, temos um a Stream, capaz de ler bits e bytes, um "input stream of
bytes". Em contrapartida, há o Reader, que também faz uma leitura, só que esta é
focada nos caracteres, "reading character streams".
Se precisamos ler uma imagem ou um PDF, por exemplo, utilizamos sempre o
Stream, já se trabalhamos com um arquivo de texto, devemos utilizar o Reader.

Java e [Link]: Streams, Reader e Writers 13


Ademais, há algo ainda mais geral que o FileInputStream, um conceito que
representa o fluxo de dados binários, que é a classe (abstrata) InputStream.

No mundo Reader, vimos duas classes, a InputStreamReader e BufferedReader. O


que ambas têm em comum é que são Readers, ou seja, compete à elas a leitura
de caracteres. Assim, o Reader também é um conceito, uma classe abstrata, que
tem estas duas classes como filhos concretos.
É fundamental compreendermos a existência destes dois mundos, dos Streams e
Readers, focados na leitura dos dados.
As classes InputStream e Reader são chamadas templates, que são aquelas que
pré-definem determinado conteúdo para as filhas.

OutputStream e Writer
Como estamos trabalhando com saída, em vez de utilizarmos o InputStream,
faremos uso do OutputStream, e em vez do Reader, teremos o Writer. Apesar das
diferentes nomenclaturas, os conceitos são os mesmos.

Java e [Link]: Streams, Reader e Writers 14


Assim, enquanto temos uma classe concreta FileOutputStream, temos acima dela
a classe mãe, abstrata, OutputStream, que é análoga à InputStream. Ela é utilizada
para manipular arquivos em formato PDF ou imagens, por exemplo.

Podemos notar que aqui está presente o padrão de decorator, onde cada objeto
decora a funcionalidade do anteriormente, da mesma forma como aconteceu no
fluxo de entrada.

Outras entradas e saídas

Java e [Link]: Streams, Reader e Writers 15


Copiaremos o conteúdo do arquivo [Link] para o [Link].
Para tanto, não queremos mostrar isso no console, ou seja, queremos escrever
para o BufferedWriter. Assim, em vez de utilizarmos o método [Link],
faremos uso do [Link](), passando como parâmetro nossa String linha.
Ao final, além de fecharmos o BufferedReader ([Link]()), temos de fechar
também o BufferedWriter
Funcionou, temos uma cópia idêntica de [Link].
A entrada concreta pode acontecer de diversas formas, bem como a saída
concreta, o importante é sabermos que a forma como elas ocorrem é menos
importante que os fluxos de entrada e de saída.
Isto pode ser observado na classe TesteCopiarArquivo, onde utilizamos sempre o
InputStream ou OutputStream, em tradução do inglês, "fluxo de entrada" e "fluxo
de saída":

Java e [Link]: Streams, Reader e Writers 16


O tipo concreto de entrada pode variar, por exemplo, pode passar a ser o teclado.
Para isso, utilizamos o [Link]:

Assim, podemos digitar qualquer texto, e continuar digitando, de qualquer forma


que o façamos, em momento algum a aplicação para de ser executada. Isso
porque não há o gatilho para que ela pare, que é o momento em que a linha for
null. Nós não somos capazes de simular manualmente a condição de saída do
laço, null.
Ao abrirmos o arquivo [Link], vemos que o que escrevemos no console foi
passado para o arquivo, mas não é garantido, já que estamos trabalhando com
um BufferedWriter. Isso significa que ele guarda todos os caracteres e, em um
momento posterior - ao fazer o close() -, escreve o que foi armazenado.

Java e [Link]: Streams, Reader e Writers 17


O programa está funcionando, mas precisamos fazer com que a execução pare
sem a necessidade de o fazermos manualmente. Em nosso laço while, criaremos
uma nova condição, além de ser diferente de null, ela não deve ser vazia. Para
isso utilizamos a negativa do método isEmpty():

A seguir, testaremos uma variação da saída concreta, o console. Neste caso,


utilizamos o [Link]:

Java e [Link]: Streams, Reader e Writers 18


Funcionou! Temos a entrada, e em seguida o resultado impresso no console, ou
seja, a saída. Para que isso aconteça de forma imediata, sem a necessidade de
uma linha em branco entre a entrada e a saída, utilizaremos o método flush().

Funcionou, temos a entrada e a impressão. O programa continua rodando, até


fazermos com que pare, gerando uma linha em branco.
Temos um código cada vez mais genérico e flexível.

Java e [Link]: Streams, Reader e Writers 19


Comunicação via Rede
A comunicação via rede se dá de forma análoga ao telefone, na parte em que
ouvimos, seria localizado o OutputStream, enquanto a extremidade por onde
falamos pode ser considerada como a InputStream. O telefone, no caso do nosso
código, se chama Socket.
Em Java, temos uma classe com esse nome e, para utilizá-la, precisamos
instanciá-la:
new Socket();

Em seguida, precisamos criar uma conexão. Por meio do Socket, podemos utilizar
um get() e obter o InputStream e o OutputStream:

Java e [Link]: Streams, Reader e Writers 20


Assim, temos três formas de entrada e saída concretas, a rede, console, e o
arquivo.

Servlet é um objeto Java que funciona como um mini servidor. Este, por sua
vez, tem por função receber e devolver dados, ou seja, [Link].

Queremos retornar, ou seja, responder, e fazemos isso por meio de um Writer(),


como é o caso em [Link](). Para isso, utilizamos uma classe
chamada PrintWriter, que assim como as classes OutputStreamWriter e
BufferedWriter, também estende Writer.
Por isso, entendemos que ela tem por finalidade escrever caracteres.
Aqui temos um exemplo de outra biblioteca, um outro contexto, no qual utilizamos
o input e output.

Java e [Link]: Streams, Reader e Writers 21


Atualmente, o mundo web é dominado por este fluxo de informações. Tudo isso
funciona graças ao [Link].

FileWriter e PrintStream

Saída com FileWriter


Nosso objetivo nesta aula será estabelecer uma saída, só que de forma mais
simples.
Trabalharemos com uma classe que é capaz de trabalhar diretamente com um
arquivo que já contém caracteres, em vez de os escrevermos diretamente no
código. Esta classe se chama FileWriter.
Comentaremos o fluxo de entrada de arquivo que havíamos criado, e
importaremos esta nova classe.
Chamaremos este FileWriter de fw, e utilizaremos um construtor que recebe uma
String referente ao nome do arquivo com o qual desejamos trabalhar, no caso
[Link].
Entretanto, percebemos que não existe o método newLine() na classe FileWriter.
Para criarmos esta linha em branco, escreveremos um novo String, e indicaremos
dentro dele que se trata de uma nova linha. Para isso, utilizamos certos caracteres
especiais, como é o caso da barra invertida (\), seguida da letra "n", portanto \n:

Isto pode variar entre sistemas operacionais, para os sistemas Linus e MacOSx
basta fazermos como está escrito acima, contudo, para o Windows OS, devemos
escrever \r\n, indicando o retorno de uma nova linha.

Java e [Link]: Streams, Reader e Writers 22


Contudo, utilizar estes caracteres especiais para criar estas linhas em branco não
é uma solução elegante, principalmente considerando estas disparidades entre
sistemas operacionais. Para deixarmos nosso código mais robusto, podemos
contar com um método do Java que nos devolve estes caracteres com base no
sistema operacional que estamos utilizando.
Começamos chamando-o com a palavra System, e em seguida selecionaremos
o método lineSeparator()

Por mais que o FileWriter atenda às nossas necessidades, ainda assim, é


recomendável continuarmos utilizando o BufferedWriter e apenas passarmos o
fw no seu construtor

Java e [Link]: Streams, Reader e Writers 23


Para simplificarmos o código, podemos mover a criação do FileWriter
diretamente para o BufferedWriter: Padrão Decorator

PrintWriter e PrintStream
Aqui, utilizaremos uma classe chamada PrintStream. Por meio dela é possível
fazermos uma impressão para um fluxo binário.

Java e [Link]: Streams, Reader e Writers 24


Abrindo a classe PrintStream, vemos que ela existe desde a versão 1.0 do Java,
enquanto as FileWriter e BufferedWriter entraram somente na versão 1.1. Ou seja,
aqueles que desejavam trabalhar com caracteres desde o Java 1.0 utilizavam,
necessariamente, a classe PrintStream. A partir disso, foram criadas ferramentas
mais especializadas.
Agora que temos o ps, podemos utilizá-lo para imprimir caracteres, e para isso há
o método println(). Ele é sobrecarregado, ou seja, possui várias versões e, dentre
elas, a que recebe uma String, e que utilizaremos para imprimir a primeira linha do
nosso arquivo de texto
Por fim, passaremos a segunda linha de texto que queremos imprimir, e
fecharemos com a referência os

Temos outra classe, que funciona de forma análoga a essa, e se chama


PrintWriter. Comentaremos o que havíamos feito, e criaremos um novo os.
O PrintStream é uma classe de mais alto nível, que aceita uma grande variedade
de construtores, como é o caso do new File().
Como os Writers e Readers foram criados após o Stream, eles têm funções muito
similares. Inicialmente existia somente o PrintStream, mas como depois surgiu o
mundo de Writers, viu-se a necessidade de criar um PrintWriter, este que não
precisa utilizar um Stream internamente.

Java e [Link]: Streams, Reader e Writers 25


Várias alternativas para estabelecer uma saída para um arquivo de texto,
como:
A classe FileWriter
A classe PrintStream
A classe PrintWriter
Alguns detalhes da classe System, como :
O atributo outé do tipo PrintStream
O método lineSeparator()devolve os caracteres que representam uma
nova linha
O método currentTimeMillis()devolve os milissegundos que passaram
desde 1 de janeiro de 1970

Leitura com Scanner


Trabalharemos com um arquivo de extensão .csv. O "c" é para a palavra
"comma", "s" para "separated", e "v" para "values", o que significa
"valores separados por vírgulas".

Criaremos uma nova classe chamada TesteLeitura2. Nela, utilizaremos a classe


Scanner, que advém do pacote [Link]. No seu construtor, passaremos o new
File, com cuidado para não confundirmos com o String source com o String
fileName

Java e [Link]: Streams, Reader e Writers 26


No construtor String Source, ao contrário dos outros métodos apresentados, que
se passa o nome do arquivo, como no caso “[Link]”. Aqui será diferente,
utilizaremos o File Source
O new File serve para representarmos o arquivo que desejamos ler, por meio de
um novo objeto. O File receberá o nome do arquivo [Link]:

A classe Scanner conta com uma série de métodos de alto nível. Utilizaremos o
nextLine(), que nos permitirá acessar a próxima linha em nosso aquivo, assim, ela
nos retornará uma String, que imprimiremos em seguida

Java e [Link]: Streams, Reader e Writers 27


Isso significa duas coisas, primeiro, que nosso programa funcionou, já que o
console exibiu a palavra true, e segundo, que há outras linhas a serem linhas, já
que a resposta foi verdadeira.
Este método será utilizado, portanto, em nosso laço, para criar um mecanismo
que funcione sempre que houver uma próxima linha a ser lida. O tipo de laço mais
indicado, neste caso, é o while:

Java e [Link]: Streams, Reader e Writers 28


Em comparação com o código da classe TesteLeitura, este é mais sucinto, e
eficaz da mesma forma. Tudo foi facilitado graças à classe Scanner, mas ela
possui ainda muitas funcionalidades que não exploramos.

Parseando arquivo
Como sabemos, a linha é do tipo String, sendo assim, utilizaremos o método
split() contido nesta classe, cuja função é separar uma String grande em pedaços
menores.
O método split() recebe como parâmetro uma String do tipo regex, que é um
conjunto de caracteres que define regras de como analisar, ou separar, uma
String maior.

Java e [Link]: Streams, Reader e Writers 29


Para fazermos esta impressão sem a necessidade da criação de um laço,
podemos utilizar a classe Arrays. Assim como temos a classe Collections, com
uma porção de métodos auxiliares, temos a Arrays, que funciona da mesma
forma, só que para o mundo dos arrays.
O split() nos ajuda, mas podemos fazer isso de forma ainda mais eficiente com o
Scanner.
Apesar de utilizarmos a mesma classe Scanner, não podemos utilizar o mesmo
objeto scanner. Ele foi criado para ler linha a linha, nosso objetivo agora é
setorizar cada uma destas linhas, e para isso deveremos criar um novo objeto.

Java e [Link]: Streams, Reader e Writers 30


Este novo Scanner se chamará linhaScanner, e receberá uma String source, ou
seja, não é o nome do arquivo, mas sim a fonte que gostaríamos de analisar.
Em seguida, precisamos indicar para o linhaScanner que a análise da linha deve
ser feita respeitando determinando critério de separação das informações, que
em nosso caso é a vírgula (,). Em programação, chamamos este critério de
delimitador, mais especificamente Delimiter. Sendo assim, utilizaremos o método
useDelimiter(), que receberá nosso padrão, que como já foi discutido, é a vírgula
(,):
A seguir, utilizaremos o Scanner para que nos retorne o próximo item do arquivo.
O método utilizado para este fim é o next(), ele nos retornará uma String. Faremos
este processo por seis vezes, para englobarmos todas as informações dos
clientes.

Java e [Link]: Streams, Reader e Writers 31


As informações de agência e conta são do tipo int, e como os transformamos em
Strings, precisaremos realizar um parseInt() - transformando o String em um tipo
mais específico, no caso, um inteiro. Contudo, para evitar procedimentos
complicados, podemos contar com o método nextInt(), para trabalhar com as
informações de agência e número da conta, e nextDouble(), para o saldo. Assim já
estamos preservando o tipo específico:

Ainda temos uma peculiaridade. No saldo, temos um ponto (.) separando os


números inteiros dos decimais, contudo, alguns lugares convencionam o ponto,
enquanto outros utilizam a vírgula (,) para este fim. O que determina se a máquina
virtual seguirá um padrão ou outro é o sistema operacional da máquina, ela
seguirá o padrão do idioma da máquina em que o código está sendo escrito. Por
exemplo, como neste curso estamos utilizando uma máquina cujo sistema está

Java e [Link]: Streams, Reader e Writers 32


em inglês, o padrão é o ponto (.), se tentarmos utilizar outro caractere, ocorrerá
um erro. Para evitar esta regra automática, podemos especificar no código a regra
que queremos seguir utilizando o método useLocale()

Formatação de valores
Até o momento, utilizamos o Scanner para ler o arquivo, e para analisar a linha
com o Delimiter - já utilizando os métodos específicos que fazem o parseInt().
A seguir, falaremos sobre a formatação. Nosso foco não será no Scanner,
tampouco no [Link].
Se tentarmos separar cada um dos valores com vírgulas, nosso código ficará
cada vez mais verboso, o que não é uma solução ideal. Para melhorarmos isso,
podemos usar a formatação na classe String, com o método format().

Java e [Link]: Streams, Reader e Writers 33


Este por sua vez recebe dois parâmetros, format e args. A ideia do primeiro é
definir o formato, de forma genérica, e em seguida - no segundo - passamos os
parâmetros, que no nosso caso são os valores que imprimimos acima.
Para estas regras de formatação, utilizamos apenas um s para representar uma
String

Ou seja, concentramos a formatação em apenas uma String, sem a necessidade


de fazer uma série de concatenações. A legibilidade do nosso código melhora
consideravelmente desta forma - concatenar muitas Strings é sempre má prática.
O resultado de format é uma nova String, que representa a o texto completo, já
com a formatação. Ele será representado pela variável valorFormatado, que
utilizaremos para imprimirmos:

Java e [Link]: Streams, Reader e Writers 34


podemos separá-los por hifens (-), se quisermos, para melhorar a legibilidade, ou
então uma vírgula (,), dois pontos (:), enfim, é possível formatarmos de maneira
mais fácil:

Na página, encontramos uma tabela contendo as abreviações disponíveis e suas


respectivas correspondências. Veremos que há um tipo específico para um inteiro
decimal, que é representado pela letra d, sendo assim, substituiremos o s pelo
tipo mais específico, já que estamos trabalhando com numéricos nos valores 2 e
3:

Java e [Link]: Streams, Reader e Writers 35


[Link]
Em projetos mais complexos temos muitas configurações a fazer para nossa
aplicação funcionar. Por exemplo, é preciso configurar usuários, senhas,
endereços ou portas para acessar outros aplicativos e serviços. Um exemplo
clássico é o acesso ao banco de dados, que precisa do login/senha, etc.
Essas configurações podem ficar dentro código fonte, mas isso exige a
recompilação do código fonte assim que uma configuração muda. O melhor seria
externalizá-las e colocá-las em um arquivo separado, por exemplo um arquivo de
texto, que não exige de compilação. Dessa forma só precisamos alterar esse
texto, sem mexer no código fonte Java.
Ótimo, e exatamente isso é feito em milhares de projetos Java e para facilitar e
padronizar mais ainda, foi criado um mini-padrão para esse tipo de arquivo. Eles
são chamados de arquivos de propriedade ou simplesmente properties.
Um arquivo properties associa o nome da configuração com o seu valor. Veja o
exemplo:

login = alura
senha = alurapass
endereco = [Link]

Java e [Link]: Streams, Reader e Writers 36


O uso dessa classe é muito simples. Veja a representação dos valores acima,
através de um objeto da classe Properties:

//import deve ser [Link]


Properties props = new Properties();
[Link]("login", "alura"); //chave, valor
[Link]("senha", "alurapass");
[Link]("endereco", "[Link]");

Escrita de properties
Agora só falta gravar um arquivo para realmente externalizar as configurações.
Para tal, você usa o método store, da classe Properties, que recebe um stream ou
writer, além dos comentários desejados:

[Link](new FileWriter("[Link]"), "algum comentá


rio");

Isso cria um arquivo [Link], com os dados do objeto acima:

#algum comentário
#Thu May 10 14:29:38 BRT 2018
senha=alurapass
login=alura
endereco=[Link]

Leitura de properties

Java e [Link]: Streams, Reader e Writers 37


Properties props = new Properties();
[Link](new FileReader("[Link]"));

String login = [Link]("login");


String senha = [Link]("senha");
String endereco = [Link]("endereco");

[Link](login + ", " + senha + ", " + endereco);

Repare que, uma vez lido o arquivo, podemos usar o método getProperty(key), da
classe Properties, para recuperar o seu valor.

Java e [Link]: Streams, Reader e Writers 38

Você também pode gostar