Преобразование InputStream в строку

JavaJavaBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В Java класс InputStream используется для чтения данных из файлов в упорядоченной последовательности. Чтобы использовать данные в виде строки, нам нужно преобразовать InputStream в строку. В этом лабе вы научитесь различным способам преобразования InputStream в строку.

Использование InputStreamReader

Класс InputStreamReader предоставляет метод read(), чтобы читать данные из InputStream в массив символов. Мы можем преобразовать массив char в строку. Создайте новый Java-исходный файл InputStreamToString.java в каталоге ~/project с таким содержанием:

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);
        }
    }
}

Для запуска кода откройте терминал, а затем скомпилируйте и запустите код с помощью следующей команды:

javac InputStreamToString.java && java InputStreamToString

Использование InputStreamReader и BufferedReader с StringBuilder

Предыдущий шаг может быть неэффективным для больших входных данных. Вместо этого мы можем использовать BufferedReader, чтобы обернуть InputStreamReader и повысить эффективность. Затем мы будем использовать объект StringBuilder, чтобы добавить строки, прочитанные из BufferedReader. Создайте новый шаг в InputStreamToString.java после шага 1 с кодом ниже:

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);
        }
    }
}

Использование InputStreamReader и BufferedReader без StringBuilder

Мы можем использовать более простой подход, используя метод lines() класса BufferedReader. Это позволяет нам избежать добавления каждой строки в отдельный экземпляр StringBuilder. Создайте новый шаг в InputStreamToString.java после шага 2 с кодом ниже:

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);
    }
}

Использование метода readAllBytes() класса InputStream

Класс InputStream в Java 9 представил метод readAllBytes(). Это позволяет эффективно преобразовать весь объект InputStream в строку за одну строку кода. Однако этот метод не рекомендуется для больших входных данных. Создайте новый шаг в InputStreamToString.java после шага 3 с кодом ниже:

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);
        }
    }
}

Использование класса Scanner

Мы также можем использовать класс Scanner, который часто используется для чтения и разбора данных, чтобы преобразовать входной поток в строку. Создайте новый шаг в InputStreamToString.java после шага 4 с кодом ниже:

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);
        }
    }
}

Использование ByteArrayOutputStream

Мы можем использовать класс ByteArrayOutputStream из пакета java.io и скопировать данные из входного потока в байтовый массив. Затем мы можем записать байтовый массив в ByteArrayOutputStream. Наконец, мы будем использовать метод toString() ByteArrayOutputStream, чтобы получить строковое представление. Создайте новый шаг в InputStreamToString.java после шага 5 с кодом ниже:

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);
        }
    }
}

Использование пакета java.nio

В пакете java.nio мы можем создать временный файл с использованием Files.createTempFile и скопировать данные из InputStream в этот файл. Затем мы можем прочитать содержимое этого временного файла в строку. Создайте новый шаг в InputStreamToString.java после шага 6 с кодом ниже:

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);
        }
    }
}

Использование библиотеки Google Guava

Библиотека Google Guava предоставляет класс CharStreams для преобразования InputStream в строку. Мы можем использовать метод toString() этого класса для этого. Он будет принимать объект Readable (например, InputStreamReader) и читать из него данные в строку. Создайте новый шаг в InputStreamToString.java после шага 7 с кодом ниже:

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);
        }
    }
}

Использование Apache Commons IO

Класс IOUtils из пакета org.apache.commons.io также содержит метод toString(). Мы можем напрямую передать объект InputStream этому методу, и он прочитает из него данные в строку. Также нам нужно указать Charset. Создайте новый шаг в InputStreamToString.java после шага 8 с кодом ниже:

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);
        }
    }
}

Использование класса StringWriter с Apache Commons IO

Мы можем использовать класс StringWriter из пакета java.io и скопировать содержимое InputStream в StringWriter. Мы будем использовать метод copy() класса IOUtils. Создайте новый шаг в InputStreamToString.java после шага 9 с кодом ниже:

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);
        }
    }
}

Резюме

В этом практическом занятии вы узнали разные способы преобразования InputStream в строку на Java. Вы можете использовать класс ByteArrayOutputStream или BufferedReader для повышения эффективности. Также доступен класс Scanner для преобразования входного потока в строку. Метод readAllBytes() подходит только для более мелких входных данных. Мы можем использовать внешние библиотеки, такие как Google Guava или Apache Commons IO, чтобы упростить процесс. Не забудьте обрабатывать исключения и закрывать InputStream, чтобы избежать утечки ресурсов.