1. Обзор
В этом руководстве мы рассмотрим как преобразовать InputStream в строку , используя Guava , Apache Commons IO и простой Java.
Эта статья является частью ссылки:/java-tutorial[серия «Java - назад к основному») здесь, на Baeldung.
2. Конвертация с гуавой
Давайте начнем с примера с Guava - используя функциональность ByteSource :
@Test
public void givenUsingGuava__whenConvertingAnInputStreamToAString__thenCorrect()
throws IOException {
String originalString = randomAlphabetic(8);
InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());
ByteSource byteSource = new ByteSource() {
@Override
public InputStream openStream() throws IOException {
return inputStream;
}
};
String text = byteSource.asCharSource(Charsets.UTF__8).read();
assertThat(text, equalTo(originalString));
}
Давайте пройдемся по шагам:
-
сначала - мы оборачиваем наш InputStream в ByteSource - и насколько я
знайте, это самый простой способ сделать это затем ** - мы рассматриваем наш ByteSource как CharSource с UTF8
кодировок.
-
наконец - мы используем CharSource , чтобы прочитать его как строку.
-
Простой способ сделать преобразование с помощью Guava ** , но поток должен быть явно закрыт; к счастью, мы можем просто использовать синтаксис try-with-resources, чтобы позаботиться об этом:
@Test
public void givenUsingGuavaAndJava7__whenConvertingAnInputStreamToAString__thenCorrect()
throws IOException {
String originalString = randomAlphabetic(8);
InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());
String text = null;
try (final Reader reader = new InputStreamReader(inputStream)) {
text = CharStreams.toString(reader);
}
assertThat(text, equalTo(originalString));
}
3. Конвертация с Apache Commons IO
Давайте теперь посмотрим, как это сделать с библиотекой Commons IO.
Важным предупреждением здесь является то, что - в отличие от Guava - ни один из этих примеров не закроет InputStream - вот почему я лично предпочитаю решение Guava.
@Test
public void givenUsingCommonsIo__whenConvertingAnInputStreamToAString__thenCorrect()
throws IOException {
String originalString = randomAlphabetic(8);
InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());
String text = IOUtils.toString(inputStream, StandardCharsets.UTF__8.name());
assertThat(text, equalTo(originalString));
}
Мы также можем использовать StringWriter для преобразования:
@Test
public void givenUsingCommonsIoWithCopy__whenConvertingAnInputStreamToAString__thenCorrect()
throws IOException {
String originalString = randomAlphabetic(8);
InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());
StringWriter writer = new StringWriter();
String encoding = StandardCharsets.UTF__8.name();
IOUtils.copy(inputStream, writer, encoding);
assertThat(writer.toString(), equalTo(originalString));
}
4. Преобразование с помощью Java - InputStream
Давайте теперь посмотрим на низкоуровневый подход с использованием простой Java - InputStream и простого StringBuilder :
@Test
public void givenUsingJava5__whenConvertingAnInputStreamToAString__thenCorrect()
throws IOException {
String originalString = randomAlphabetic(DEFAULT__SIZE);
InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());
StringBuilder textBuilder = new StringBuilder();
try (Reader reader = new BufferedReader(new InputStreamReader
(inputStream, Charset.forName(StandardCharsets.UTF__8.name())))) {
int c = 0;
while ((c = reader.read()) != -1) {
textBuilder.append((char) c);
}
}
assertEquals(textBuilder.toString(), originalString);
}
5. Преобразование с помощью Java и Scanner
Далее - давайте посмотрим на простой пример Java - используя стандартный текст Scanner :
@Test
public void givenUsingJava7__whenConvertingAnInputStreamToAString__thenCorrect()
throws IOException {
String originalString = randomAlphabetic(8);
InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());
String text = null;
try (Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF__8.name())) {
text = scanner.useDelimiter("\\A").next();
}
assertThat(text, equalTo(originalString));
}
Обратите внимание, что InputStream будет закрыто закрытием Scanner .
Единственная причина, по которой это пример Java 7, а не Java 5, это использование оператора try-with-resources - превращение его в стандартный блок try-finally будет прекрасно компилироваться с Java 5 .
6. Преобразование с использованием ByteArrayOutputStream
Наконец, давайте посмотрим на другой простой пример Java, на этот раз используя класс ByteArrayOutputStream :
@Test
public final void givenUsingPlainJava__whenConvertingAnInputStreamToString__thenCorrect()
throws IOException {
String originalString = randomAlphabetic(8);
InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[]data = new byte[1024];
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
byte[]byteArray = buffer.toByteArray();
String text = new String(byteArray, StandardCharsets.UTF__8);
assertThat(text, equalTo(originalString));
}
В этом примере сначала InputStream преобразуется в ByteArrayOutputStream путем чтения и записи байтовых блоков, затем OutputStream преобразуется в байтовый массив, который используется для создания String .
7. Преобразование с помощью java.nio
Другое решение - скопировать содержимое InputStream в файл, а затем преобразовать его в String:
@Test
public final void givenUsingTempFile__whenConvertingAnInputStreamToAString__thenCorrect()
throws IOException {
String originalString = randomAlphabetic(DEFAULT__SIZE);
InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());
Path tempFile = Files.createTempDirectory("").resolve(UUID.randomUUID().toString() + ".tmp");
Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE__EXISTING);
String result = new String(Files.readAllBytes(tempFile));
assertThat(result, equalTo(originalString));
}
Здесь мы используем класс java.nio.file.Files для создания временного файла, а также для копирования содержимого InputStream в файл.
Затем тот же класс используется для преобразования содержимого файла в String с помощью метода readAllBytes () .
8. Заключение
После компиляции наилучшего способа сделать простое преобразование - InputStream в String - в правильном и удобочитаемом виде - и после просмотра стольких совершенно разных ответов и решений - я думаю, что нужна четкая и краткая лучшая практика для этого .
Реализация всех этих примеров и фрагментов кода может быть найдена на GitHub - это проект на основе Maven, так что должно быть легко импортировать и запускать как есть.