Oi! Hoje falaremos sobre a classe Java PrintStream e tudo o que ela pode fazer. Na verdade, você já conhece dois métodos da classe PrintStream . Eles são print() e println() , que você provavelmente usa todos os dias :) Como a variável System.out é um objeto PrintStream , você está chamando um dos métodos dessa classe quando chama System.out.println() . O objetivo geral da classe PrintStream é enviar informações para algum fluxo.
Esta classe tem vários construtores. Aqui estão alguns dos mais comumente usados:

- PrintStream(OutputStream outputStream)
- PrintStream(File outputFile) lança FileNotFoundException
- PrintStream(String outputFileName) lança FileNotFoundException
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Main {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
filePrintStream.println(222);
filePrintStream.println("Hello world");
filePrintStream.println(false);
}
}
Esse código criará um arquivo test.txt na área de trabalho (se ainda não existir) e gravará sequencialmente nosso número, string e booleano nele. Aqui está o conteúdo do arquivo depois de executarmos o programa:
222
Hello world!
false
Como dissemos acima, você não precisa passar um objeto File . Basta passar o caminho do arquivo para o construtor:
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Main {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream("C:\\Users\\Username\\Desktop\\test.txt");
filePrintStream.println(222);
filePrintStream.println("Hello world");
filePrintStream.println(false);
}
}
Este código faz o mesmo que o código anterior. Outro método interessante que merece nossa atenção é printf() , que produz uma saída baseada em uma string de formato. O que é uma "string de formato"? Deixe-me dar um exemplo:
import java.io.IOException;
import java.io.PrintStream;
public class Main {
public static void main(String[] args) throws IOException {
PrintStream printStream = new PrintStream("C:\\Users\\Steve\\Desktop\\test.txt");
printStream.println("Hello!");
printStream.println("I'm a robot!");
printStream.printf("My name is %s. I am %d!", "Amigo", 18);
printStream.close();
}
}
Aqui, em vez de declarar explicitamente o nome e a idade do nosso robô na string, colocamos espaços reservados para essa informação, representados por %s e %d . E passamos como argumentos os dados que irão substituí-los. No nosso caso, esta é a string " Amigo " e o número 18. Poderíamos criar outro espaço reservado, digamos %b , e passar outro argumento. Por que nós precisamos disso? Acima de tudo, para uma maior flexibilidade. Se o seu programa exigir que você exiba uma mensagem de boas-vindas com frequência, você terá que digitar manualmente o texto necessário para cada novo robô. Você não pode nem tornar esse texto uma constante, já que todos têm nomes e idades diferentes! Mas usando este novo método, você pode isolar a saudação em uma constante e, se necessário, simplesmente alterar os argumentos passados para o método printf() .
import java.io.IOException;
import java.io.PrintStream;
public class Main {
private static final String GREETINGS_MESSAGE = "My name is %s. I am %d!";
public static void main(String[] args) throws IOException {
PrintStream printStream = new PrintStream("C:\\Users\\Steve\\Desktop\\test.txt");
printStream.println("Hello!");
printStream.println("We are robots!");
printStream.printf(GREETINGS_MESSAGE, "Amigo", 18);
printStream.printf(GREETINGS_MESSAGE, "R2-D2", 35);
printStream.printf(GREETINGS_MESSAGE, "C-3PO", 35);
printStream.close();
}
}
Substituindo System.in
Nesta lição, vamos "combater o sistema" e aprender como substituir a variável System.in para redirecionar a saída do sistema para onde quisermos. Você pode esquecer o que é System.in , mas nenhum aluno do CodeGym jamais esquecerá esta construção:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.in (assim como System.out ) é uma variável estática da classe System . Mas ao contrário de System.out , ele faz referência a outra classe, ou seja, InputStream . Por padrão, System.in é um fluxo que lê dados de um dispositivo do sistema — o teclado. No entanto, assim como com System.out , podemos substituir o teclado como fonte de dados. Podemos ler dados de onde quisermos! Vejamos um exemplo:
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
String greetings = "Hi! My name is Amigo!\nI'm learning Java on the CodeGym website.\nOne day I will become a cool programmer!\n";
byte[] bytes = greetings.getBytes();
InputStream inputStream = new ByteArrayInputStream(bytes);
System.setIn(inputStream);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str;
while ((str = reader.readLine())!= null) {
System.out.println(str);
}
}
}
Então, o que nós fizemos? System.in geralmente é vinculado ao teclado. Mas não queremos ler os dados do teclado: vamos fazer com que os dados sejam lidos de uma string comum! Criamos uma string e a obtivemos como uma matriz de bytes. Por que precisamos de bytes? O problema é que InputStream é uma classe abstrata, então não podemos criar uma instância dela diretamente. Temos que escolher um de seus descendentes. Por exemplo, podemos escolher ByteArrayInputStream . É simples e seu nome já nos diz como funciona: sua fonte de dados é uma matriz de bytes. Então criamos um array de bytes e passamos para o construtor do nosso stream que vai ler os dados. E agora está tudo pronto! Agora só precisamos usar o System.setIn()para definir explicitamente o valor da variável in . Sem , você deve se lembrar, também não era possível definir o valor da variável diretamente: tínhamos que usar o método setOut() . Depois de atribuir nosso InputStream à variável System.in , queremos verificar se atingimos nosso objetivo. Nosso velho amigo BufferedReader vem em nosso auxílio aqui. Normalmente, esse código abriria o console no IntelliJ IDEA e leria os dados inseridos no teclado.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str;
while ((str = reader.readLine())!= null) {
System.out.println(str);
}
Mas agora, ao executá-lo, você verá que nossa string é simplesmente exibida no console. Não há leitura do teclado. Substituímos a fonte de dados. Não é mais o teclado, mas a nossa corda! É simples assim :) Na lição de hoje, conhecemos uma nova classe e exploramos um pequeno novo hack para trabalhar com E/S. Agora é hora de voltar ao curso e completar algumas tarefas :) Até a próxima aula!
GO TO FULL VERSION