Java Nio

Stream

Java N.IO Stream

Sequência de dados

Uma Stream é uma sequência de dados. Em Java, uma stream é composta de bytes. É chamado de stream (stream) porque é como um riacho de água que continua a fluir.

Input vs Output

A explicação das classes OutputStream e InputStream são fornecidas abaixo:

Vamos entender o funcionamento do Java OutputStream e InputStream pela figura abaixo.

arquivos

OutputStream

O aplicativo Java usa um fluxo de saída para gravar dados em um destino; pode ser um arquivo, uma matriz, dispositivo periférico ou soquete.

A classe OutputStream é uma classe abstrata. É a superclasse de todas as classes que representam um fluxo de saída de bytes. Um fluxo de saída aceita bytes de saída e os envia para algum coletor.

arquivos

Vamos explorar os principais métodos da classe e sub-classes de OutputStream.

details public void close() throws IOException
Esse método fecha o fluxo de saída atual e libera todos os recursos do sistema associados a ele. O fluxo fechado não pode ser reaberto e as operações não podem ser executadas dentro dele.
details public void close() throws IOException Esse método fecha o fluxo de saída atual e libera todos os recursos do sistema associados a ele. O fluxo fechado não pode ser reaberto e as operações não podem ser executadas dentro dele.
details public void flush() throws IOException Ele libera o fluxo de saída atual e força qualquer saída armazenada em buffer a ser gravada.
details public void write(byte[ ] b) throws IOException Esse método grava os bytes bytes.length da matriz de bytes especificada no fluxo de saída.
details public void write(byte[ ] b ,int off ,int len) throws IOException Ele grava até len bytes de dados no fluxo de saída. Aqui, o off é o deslocamento inicial na matriz de buffer b, e o len representa o número máximo de bytes a serem gravados no fluxo de saída.
details public abstract void write(int b) throws IOException O método acima grava os bytes específicos no fluxo de saída. Não retorna um valor.

Escrevendo em arquivos

Abaixo iremos demonstrar como escrever byte a byte de um conteúdo no formato String.


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class JavaNIO {
    public static void main(String[] args) {
        try {

            // antes de pensar em escrever, elabore e confira o conteúdo
            String conteudo = "Hoje aprendemos sobre Java IO - OutputStream e escrita em arquivos físicos no sistema operacional";

            // O java necessita de uma barra dupla para windows
            File aulaFile = new File("C:\\arquivos\\","aula-java-nio.txt");
            // Observe acima que File está recebendo dois parâmetros: diretório e nome do arquivo

            /**
             * Se preferir crie um objeto file somente para o diretório e verifique se o existe, e crie caso necessário
             */

            FileOutputStream output = new FileOutputStream(aulaFile); //poderia ser a String do endereço completo do arquivo

            char [] caracteres = conteudo.toCharArray();
            // inicializa x to 0
            int x = 0;
            // equanto houver caracteres na string com base na posição
            while (x < conteudo.length()) {
                // escreve caractere por caractere
                output.write(caracteres[x++]);
            }
            // fecha o arquivo
            output.close();


        } catch (IOException e) {
            // um erro acontecerá se o diretório não existir previamente
            // certifique-se de complementar com a lógica de criar o diretório previamente.
            e.printStackTrace();
        }
    }
}

Percebemos que para uma operação simples foram necessárias algumas linhas de códigos para ser possível cada caractere do conteúdo por vez. Para melhorar o nosso programa iremos desfrutar da combinação das classes FileOutputStream com a ByteArrayOutputStream.

try {
    String conteudo = "Hoje aprendemos sobre Java IO - OutputStream e escrita em arquivos físicos no sistema operacional";
    File aulaFile = new File("C:\\arquivos\\","aula-java-nio.txt");
    FileOutputStream output = new FileOutputStream(aulaFile); //poderia ser a String do endereço completo do arquivo

    ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
    byteOutput.write(conteudo.getBytes());
    byteOutput.writeTo(output);

    output.close();
} catch (IOException e) {
    e.printStackTrace();
}

InputStream

O aplicativo Java usa um fluxo de entrada para ler dados de uma origem; pode ser um arquivo, uma matriz, dispositivo periférico ou soquete.

arquivos

🚨 Atenção
Nesta nossa abordagem estamos explorando o conceito de Stream somente no contexto em trabalhar com arquivos físicos em seu sistema operacional.
Recomendamos explorar de acordo com as hierarquias citadas acima cada alternativa correspondentemente.

Anteriomente conseguimos escrever um conteúdo em arquivo C:\arquivos\aula-java-nio.txt, chegou a hora de ler o conteúdo que está no arquivo e realizar as operações de acordo com os requisitos da sua aplicação.

A classe InputStream é uma superclasse abstrata do pacote java.io e é usada para ler os dados de uma fonte de entrada. Em outras palavras, lendo dados de arquivos ou de um teclado, etc.

Vamos explorar os principais métodos da classe e sub-classes de InputStream.

details public abstract int read() throws IOException
O método acima ajuda a retornar os dados do próximo byte no fluxo de entrada. O valor retornado está entre 0 a 255. Se nenhum byte for lido, o código retorna -1, que indica o fim do arquivo.
details public int available() throws IOException
O método acima retorna o número de bytes que podem ser lidos do fluxo de entrada.
details public void close() throws IOException
The method above closes the current input stream and releases any system resources associated with it.
details public int read(byte[ ] b) throws IOException
O método acima lê os bytes do fluxo de entrada e armazena cada byte na matriz do buffer. Ele retorna o número total de bytes armazenados na matriz do buffer. Se não houver nenhum byte no fluxo de entrada, ele retornará -1, pois o fluxo está no final do arquivo.
details public void reset() throws IOException
Ele reposiciona o fluxo para a última posição de marca chamada. O método reset não faz nada para a classe de fluxo de entrada, exceto lançar uma exceção.
details public long skip(long n) throws IOException
Este método descarta n bytes de dados do fluxo de entrada.

Podemos criar um objeto da classe de fluxo de entrada usando a palavra-chave new. Como estamos em contexto de ler um arquivo, A classe de FileInputStream tem vários tipos de construtores.

O código a seguir usa o nome do arquivo como uma string para ler os dados armazenados no arquivo C:\arquivos\aula-java-nio.txt.


public class JavaNIO {
    public static void main(String[] args) {
        try {
            InputStream conteudoArquivo = new FileInputStream("C:\\arquivos\\aula-java-nio.txt");
            // inicializando a variável caractere
            int caractere = 0;
            // enquanto houver caractere após cada deslocamento

            StringBuilder conteudo = new StringBuilder();
            while ((caractere = conteudoArquivo.read()) != -1) {
                //capturando cada caractere e atualizando a variável conteúdo
                conteudo.append ((char) caractere);
            }
            // fechando o fluxo
            conteudoArquivo.close();

            System.out.println(conteudo.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
✔️ Conclusão
Acabamos de chegar a conclusão que para atender um requisito relativamente simples, faz-se necessário, compreender a partir de agora conceitos e fundamentos da linguagem como dominar o essencial de cada classe