Olá! Hoje falaremos sobre a classe
PrintStream
e tudo o que ela pode fazer. Na verdade, você já está familiarizado com dois métodos da classe PrintStream
. Esses são os métodos print()
e println()
que você provavelmente usa todos os dias :) Como uma variável System.out
é um objeto PrintStream
, quando você chama um método System.out.println()
, você está chamando um método dessa classe específica. O objetivo geral da classe PrintStream
é enviar informações para algum fluxo. Esta classe possui vários construtores. Aqui estão alguns dos mais comuns:
PrintStream(OutputStream outputStream)
PrintStream(File outputFile) throws FileNotFoundException
PrintStream(String outputFileName) throws FileNotFoundException
PrintStream
, por exemplo, o nome do arquivo no qual queremos gerar os dados. Ou, alternativamente, o próprio objeto File
. Vejamos como isso funciona com exemplos:
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);
}
}
Este código criará um arquivo na área de trabalho test.txt
(se ainda não existir) e escreverá nosso número, string e boolean
variável lá sequencialmente. Aqui está o conteúdo do nosso arquivo após a execução do programa:
222
Hello world!
false
Como dissemos acima, não é necessário passar o objeto arquivo em si File
. Você só precisa especificar o caminho para ele no 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 fará o mesmo que o anterior. Outro método interessante de observar é printf()
a saída de string formatada. O que significa "string formatada"? Para explicar, vou 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\\Евгений\\Desktop\\test.txt");
printStream.println("Hello!");
printStream.println("I'm robot!");
printStream.printf("My name is %s, my age is %d!", "Amigo", 18);
printStream.close();
}
}
Aqui, em vez de escrever explicitamente o nome e a idade do nosso robô em uma linha, parece que deixamos “espaço livre” para essas informações usando ponteiros %s
e %d
. E passamos os dados que deveriam estar nesses locais como parâmetros. No nosso caso, esta é a string " Amigo " e o número 18. Poderíamos, por exemplo, criar outro espaço: digamos, %b
, e passar outro parâmetro. Para que serve? Em primeiro lugar, para aumentar a flexibilidade. Se o seu programa precisar exibir frequentemente uma mensagem de boas-vindas, você terá que inserir manualmente o texto necessário para cada novo robô. Você nem conseguirá colocar esse texto em uma constante: os nomes e as idades de cada pessoa são diferentes! Mas usando o novo método, você pode gerar uma string com uma saudação para uma constante e, se necessário, simplesmente alterar os parâmetros no método printf()
.
import java.io.IOException;
import java.io.PrintStream;
public class Main {
private static final String GREETINGS_MESSAGE = "My name is %s, my age is %d!";
public static void main(String[] args) throws IOException {
PrintStream printStream = new PrintStream("C:\\Users\\Евгений\\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();
}
}
Falsificação de System.in
Nesta palestra iremos “combater o sistema” e aprender como substituir uma variávelSystem.in
e redirecionar a saída do sistema para o local que necessitamos. Você pode ter esquecido o que é System.in
, mas nenhum aluno de JavaRush jamais esquecerá esta construção:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.in
(like System.out
) é uma variável de classe estática System
. Mas, ao contrário System.out
, pertence a uma classe diferente, nomeadamente, a InputStream
. Por padrão System.in
, este é um thread que lê dados do dispositivo do sistema – o teclado. Porém, como no caso de System.out
, podemos substituir a fonte de dados, e a leitura ocorrerá não no teclado, mas no local que precisamos! Vejamos um exemplo:
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
String greetings = "Hello! Меня зовут Амиго!\nЯ изучаю Java на сайте JavaRush.\nОднажды я стану крутым программистом!\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? Geralmente System.in
“amarrado” ao teclado. Mas não queremos que os dados sejam lidos no teclado: deixe-os ser lidos em uma linha normal de texto! Criamos uma string e a recebemos como um array de bytes. Por que precisamos de bytes? O fato é que InputStream
é uma classe abstrata e não podemos criar uma instância dela. Você terá que escolher alguma classe entre seus herdeiros. Por exemplo, podemos pegar ByteArrayInputStream
. É simples, e só pelo nome já fica claro como funciona: sua fonte de dados é um array de bytes. Então criamos esse mesmo array de bytes e passamos para o nosso construtor stream
, que irá ler os dados. Na verdade, já está tudo pronto! Agora só precisamos usar o método System.setIn()
para definir explicitamente o valor da variável in
. No caso de out
, como você se lembra, também era claramente impossível definir o valor da variável: era necessário usar um método especial setOut()
. Depois de atribuirmos InputStream
a variável que criamos System.in
, precisamos verificar se nossa ideia funcionou. Um velho amigo nos ajudará com isso - BufferedReader
. Em uma situação normal, esse código faria com que um console fosse aberto em seu Intellij IDEa e os dados inseridos no teclado seriam lidos a partir daí.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str;
while ((str = reader.readLine())!= null) {
System.out.println(str);
}
Mas ao executá-lo agora, você verá que nosso texto do programa será simplesmente enviado para o console, não haverá leitura do teclado. Mudamos a fonte de dados, agora não é o teclado, mas sim a nossa string! É tão fácil e simples :) Na palestra de hoje conhecemos uma nova classe e vimos um novo pequeno “hack” para trabalhar com I/O. É hora de voltar ao curso e resolver alguns problemas :) Até a próxima palestra!
GO TO FULL VERSION