JavaRush /Blogue Java /Random-PT /E/S em Java. Classes FileInputStream, FileOutputStream, B...

E/S em Java. Classes FileInputStream, FileOutputStream, BufferedInputStream

Publicado no grupo Random-PT
Olá! Na palestra de hoje continuaremos a conversa sobre fluxos de entrada e saída em Java, ou Java I/O (“entrada-saída”), para abreviar. Esta não é a primeira palestra sobre este tópico e não será a última :) Acontece que Java como linguagem oferece muitas oportunidades para trabalhar com entrada/saída. Existem muitas classes que implementam essa funcionalidade, então nós as dividimos em várias palestras para que você não fique confuso no início :) E/S em Java.  Classes FileInputStream, FileOutputStream, BufferedInputStream - 1Nas palestras anteriores abordamos BufferedReader , bem como as classes abstratas InputStream & OutputStream e várias descendentes. Hoje veremos 3 novas classes: FileInputStream , FileOutputStream e BufferedInputStream .

Classe FileOutputStream

O objetivo principal da classe FileOutputStream é gravar bytes em um arquivo. Nada complicado :) FileOutputStream é uma das implementações da classe abstrata OutputStream . No construtor, os objetos desta classe seguem o caminho para o arquivo de destino (no qual os bytes precisam ser gravados) ou um objeto da classe File. Vejamos os dois exemplos:
public class Main {

   public static void main(String[] args) throws IOException {


       File file = new File("C:\\Users\\Username\\Desktop\\test.txt");
       FileOutputStream fileOutputStream = new FileOutputStream(file);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Ao criar um objeto, Fileespecificamos no construtor o caminho onde ele deve estar localizado. Não há necessidade de criá-lo antecipadamente: se não existir, o próprio programa o criará. Você pode fazer isso sem criar um objeto extra e apenas passar uma string com o endereço:
public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt");

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
O resultado em ambos os casos será o mesmo. Podemos abrir nosso arquivo e ver lá:

Hello! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
No entanto, há uma ressalva aqui. Tente executar o código do exemplo acima várias vezes seguidas e, em seguida, observe o arquivo e responda à pergunta: quantas linhas você vê escritas nele? Apenas um. Mas você executou o código várias vezes. Porém, acontece que os dados foram sobrescritos todas as vezes, substituindo os antigos. E se não estivermos satisfeitos com isso e precisarmos de gravação sequencial? E se quisermos escrever nossa saudação em um arquivo três vezes seguidas? Tudo é simples aqui. Como a linguagem em si não pode saber que tipo de comportamento precisamos em cada caso, FileOutputStreamvocê pode passar um parâmetro adicional para o construtor - boolean append. Se o seu valor for true , os dados serão gravados no final do arquivo. Se false (e o valor padrão for false ), os dados antigos serão apagados e os novos dados serão gravados. Vamos testar e executar nosso código modificado três vezes:
public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!\r\n";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Resultado no arquivo:

Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Outra coisa! Lembre-se desse recurso ao usar classes de E/S. Ao mesmo tempo, eu tinha que ficar horas sentado em tarefas para entender para onde iam meus dados antigos dos arquivos :) E claro, como no caso de outras classes de I/O, não se esqueça de liberar recursos por meio do close().

Classe FileInputStream

A classe tem FileInputStreamo propósito oposto – ler bytes de um arquivo. Assim como FileOutputStreamherda OutputStream, esta classe deriva da classe abstrata InputStream. Vamos escrever várias linhas de texto em nosso texto “ test.txt ”:

«So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters»
E/S em Java.  Classes FileInputStream, FileOutputStream, BufferedInputStream - 2 Isto é o que acontece com a implementação da leitura de dados de um arquivo usando FileInputStream:
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       int i;

       while((i=fileInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
Lemos um byte do arquivo, convertemos os bytes lidos em caracteres e os enviamos para o console. E aqui está o resultado no console:

So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters

Classe BufferedInputStream

Acho que, dado o conhecimento de palestras anteriores, você pode facilmente dizer por que a aula é necessária BufferedInputStreame quais vantagens ela tem FileInputStream:) Já conhecemos streams em buffer, então tente adivinhar (ou lembre-se) antes de continuar lendo :) Streams em buffer são necessários principalmente para otimizar E/S. Acessar uma fonte de dados, como ler um arquivo, é uma operação que exige muito desempenho. E acessar o arquivo para ler um byte de cada vez é um desperdício. Portanto, BufferedInputStreamele lê os dados não um byte por vez, mas em blocos e os armazena temporariamente em um buffer especial. Isso nos permite otimizar o funcionamento do programa reduzindo o número de acessos ao arquivo. Vamos ver como é:
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
Aqui criamos um objeto BufferedInputStream. Ele aceita um objeto ou qualquer um de seus sucessores como input InputStream, então o anterior FileInputStreamservirá. Leva o tamanho do buffer em bytes como um parâmetro adicional. Agora, graças a isso, os dados do arquivo serão lidos não um byte por vez, mas 200 por vez! Imagine o quanto reduzimos o número de acessos a arquivos. Para comparar o desempenho, você pode pegar um arquivo de texto grande com vários megabytes de tamanho e comparar quanto tempo leva para lê-lo e enviá-lo para o console em milissegundos usando FileInputStreame BufferedInputStream. Aqui estão os dois exemplos de código:
public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}



public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf");


       int i;

       while((i = fileInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}
Ao ler um arquivo de 1,5 MB em meu computador, FileInputStreamele fez o trabalho em aproximadamente 3.500 milissegundos, mas aqui BufferedInputStreamele fez o trabalho em aproximadamente 1.700 milissegundos. Como você pode ver, o fluxo em buffer otimizou o desempenho do programa em 2 vezes! :) Continuaremos estudando aulas de I/O - até breve!
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION