Converter InputStream para String

JavaBeginner
Pratique Agora

Introdução

Em Java, a classe InputStream é utilizada para ler dados de arquivos em uma sequência ordenada. Para usar os dados como uma string, precisamos converter o InputStream em uma String. Este laboratório irá ensiná-lo diferentes maneiras de converter um InputStream em uma string.

Usando InputStreamReader

A classe InputStreamReader fornece um método read() para ler dados de um InputStream em um array de caracteres. Podemos converter o array de caracteres em uma string. Crie um novo arquivo fonte Java InputStreamToString.java no diretório ~/project com o seguinte conteúdo:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        InputStreamReader reader = new InputStreamReader(input);
        char[] charArray = new char[256];
        reader.read(charArray);
        return new String(charArray);
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Para executar o código, abra o terminal, compile e execute o código com o seguinte comando:

javac InputStreamToString.java && java InputStreamToString

Usando InputStreamReader e BufferedReader com StringBuilder

O passo anterior pode ser ineficiente para entradas maiores. Em vez disso, podemos usar um BufferedReader para encapsular o InputStreamReader para melhorar a eficiência. Então, usaremos um objeto StringBuilder para anexar as linhas lidas do BufferedReader. Crie um novo passo em InputStreamToString.java após o Passo 1 com o seguinte código:

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        StringBuilder builder = new StringBuilder();
        InputStreamReader reader = new InputStreamReader(input);
        BufferedReader bufferedReader = new BufferedReader(reader);
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            builder.append(line);
        }
        return builder.toString();
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando InputStreamReader e BufferedReader sem StringBuilder

Podemos usar uma abordagem mais simples usando o método lines() da classe BufferedReader. Isso nos permite pular a anexação de cada linha a uma instância separada de StringBuilder. Crie um novo passo em InputStreamToString.java após o Passo 2 com o seguinte código:

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        InputStreamReader reader = new InputStreamReader(input);
        BufferedReader bufferedReader = new BufferedReader(reader);
        String str = bufferedReader.lines().collect(Collectors.joining("\n"));
        return str;
    }

    public static void main(String[] args) {
        InputStream input = new ByteArrayInputStream("hello world".getBytes());
        String strFromInputStream = inputStreamToString(input);
        System.out.print("String from the Input Stream is: " + strFromInputStream);
    }
}

Usando o método readAllBytes() do InputStream

A classe InputStream introduziu o método readAllBytes() no Java 9. Isso pode converter eficientemente todo o objeto InputStream em uma string em uma única linha de código. No entanto, este método não é recomendado para entradas maiores. Crie um novo passo em InputStreamToString.java após o Passo 3 com o seguinte código:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        return new String(input.readAllBytes());
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando a Classe Scanner

Também podemos usar a classe Scanner, uma classe comumente usada para ler e analisar dados, para converter o fluxo de entrada em uma string. Crie um novo passo em InputStreamToString.java após o Passo 4 com o seguinte código:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        Scanner scanner = new Scanner(input);
        StringBuilder builder = new StringBuilder();
        while (scanner.hasNext()) {
            builder.append(scanner.nextLine());
        }
        return builder.toString();
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando ByteArrayOutputStream

Podemos usar a classe ByteArrayOutputStream no pacote java.io e copiar dados do fluxo de entrada para o array de bytes. Então, podemos escrever o array de bytes no ByteArrayOutputStream. Finalmente, usaremos o método toString() do ByteArrayOutputStream para obter a representação em string. Crie um novo passo em InputStreamToString.java após o Passo 5 com o seguinte código:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[128];
        int length;
        while ((length = input.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, length);
        }
        return byteArrayOutputStream.toString();
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando o Pacote java.nio

No pacote java.nio, podemos criar um arquivo temporário usando Files.createTempFile e copiar os dados do InputStream para este arquivo. Então, podemos ler o conteúdo deste arquivo temporário em uma string. Crie um novo passo em InputStreamToString.java após o Passo 6 com o seguinte código:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        Path file = Files.createTempFile(null, null);
        Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
        return new String(Files.readAllBytes(file));
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);
        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando a Biblioteca Google Guava

A biblioteca Google Guava fornece a classe CharStreams para converter um InputStream em uma string. Podemos usar o método toString() desta classe para fazer isso. Ele receberá um objeto Readable (como o InputStreamReader) e lerá os dados dele em uma string. Crie um novo passo em InputStreamToString.java após o Passo 7 com o seguinte código:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.google.common.io.CharStreams;

public class InputStreamToString {
    public static String inputStreamToString(InputStream input) throws IOException {
        try(InputStreamReader reader = new InputStreamReader(input)) {
            return CharStreams.toString(reader);
        }
    }

    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = inputStreamToString(input);
            System.out.print("String from the Input Stream is: " + strFromInputStream);

        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando Apache Commons IO

A classe IOUtils do pacote org.apache.commons.io também contém um método toString(). Podemos passar diretamente o objeto InputStream para este método, e ele lerá os dados dele em uma string. Também precisamos especificar um Charset. Crie um novo passo em InputStreamToString.java após o Passo 8 com o seguinte código:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;

public class InputStreamToString {
    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            String strFromInputStream = IOUtils.toString(input, StandardCharsets.UTF_8.name());
            System.out.print("String from the Input Stream is: " + strFromInputStream);

        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Usando a Classe StringWriter com Apache Commons IO

Podemos usar a classe StringWriter do pacote java.io e copiar o conteúdo do InputStream para o StringWriter. Usaremos o método copy() da classe IOUtils. Crie um novo passo em InputStreamToString.java após o Passo 9 com o seguinte código:

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;

public class InputStreamToString {
    public static void main(String[] args) {
        try {
            InputStream input = new ByteArrayInputStream("hello world".getBytes());
            StringWriter sw = new StringWriter();
            IOUtils.copy(input, sw, StandardCharsets.UTF_8.name());
            String strFromInputStream = sw.toString();
            System.out.print("String from the Input Stream is: " + strFromInputStream);

        } catch(Exception e) {
            System.out.print(e);
        }
    }
}

Resumo

Neste laboratório, você aprendeu diferentes maneiras de converter um InputStream em uma string em Java. Você pode usar a classe ByteArrayOutputStream ou a classe BufferedReader para melhorar a eficiência. A classe Scanner também está disponível para converter o fluxo de entrada em uma string. O método readAllBytes() é adequado apenas para entradas menores. Podemos usar bibliotecas externas como Google Guava ou Apache Commons IO para simplificar o processo. Lembre-se de tratar as exceções e fechar o InputStream para evitar vazamentos de recursos.