Если у вас есть объект java.io.InputStream
, как вы должны обработать этот объект и получить строку? Предположим, у меня есть InputStream
, содержащий текстовые данные, и я хочу преобразовать его в строку, чтобы, например, записать ее в файл лога.
Какой самый простой способ взять InputStream
и преобразовать его в строку?
1 2 3 |
public String convertStreamToString(InputStream is) { // ??? } |
Способы преобразования InputStream в строку
Я нашел 11 основных способов сделать это (см. ниже). И я написал несколько тестов производительности (см. результаты ниже):
Использование IOUtils.toString (Apache Utils)
1 |
String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8); |
Использование потоков CharStreams
(Guava)
1 2 3 |
String result = CharStreams.toString(new InputStreamReader( inputStream, Charsets.UTF_8) ); |
Использование сканера (JDK)
1 2 |
Scanner s = new Scanner(inputStream).useDelimiter("\\A"); String result = s.hasNext() ? s.next() : ""; |
Использование Stream API (Java 8). Предупреждение: Это решение конвертирует различные переносы строк (например, \r\n
) в \n
.
1 2 |
String result = new BufferedReader(new InputStreamReader(inputStream)) .lines().collect(Collectors.joining("\n")); |
Использование параллельного Stream API (Java 8). Предупреждение: Это решение конвертирует различные переносы строк (например, \r\n
) в \n
.
1 2 |
String result = new BufferedReader(new InputStreamReader(inputStream)) .lines().parallel().collect(Collectors.joining("\n")); |
Использование InputStreamReader
и StringBuilder
(JDK)
1 2 3 4 5 6 7 8 9 10 |
int bufferSize = 1024; char[] buffer = new char[bufferSize]; StringBuilder out = new StringBuilder(); Reader in = new InputStreamReader(stream, StandardCharsets.UTF_8); for (int numRead; (numRead = in.read(buffer, 0, buffer.length)) > 0; ) { out.append(buffer, 0, numRead); } return out.toString(); |
Использование StringWriter
и IOUtils.copy
(Apache Commons)
1 2 3 |
StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, "UTF-8"); return writer.toString(); |
Использование ByteArrayOutputStream
и inputStream.read
(JDK)
1 2 3 4 5 6 7 8 9 |
ByteArrayOutputStream result = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; for (int length; (length = inputStream.read(buffer)) != -1; ) { result.write(buffer, 0, length); } // StandardCharsets.UTF_8.name() > JDK 7 return result.toString("UTF-8"); |
Использование BufferedReader
(JDK). Предупреждение: Это решение преобразует различные переносы строк (например, \n\r
) в системное свойство line.separator
(например, в Windows в «\r\n»).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
String newLine = System.getProperty("line.separator"); BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream) ); StringBuilder result = new StringBuilder(); for (String line; (line = reader.readLine()) != null; ) { if (result.length() > 0) { result.append(newLine); } result.append(line); } return result.toString(); |
Использование BufferedInputStream
и ByteArrayOutputStream
(JDK)
1 2 3 4 5 6 7 8 9 |
BufferedInputStream bis = new BufferedInputStream(inputStream); ByteArrayOutputStream buf = new ByteArrayOutputStream(); for (int result = bis.read(); result != -1; result = bis.read()) { buf.write((byte) result); } // StandardCharsets.UTF_8.name() > JDK 7 return buf.toString("UTF-8"); |
Использование inputStream.read()
и StringBuilder
(JDK). Предупреждение: Данное решение имеет проблемы с Unicode, например, с русским текстом (корректно работает только с не-Unicode текстом)
1 2 3 4 5 |
StringBuilder sb = new StringBuilder(); for (int ch; (ch = inputStream.read()) != -1; ) { sb.append((char) ch); } return sb.toString(); |
Внимание:
- Решения 4, 5 и 9 преобразуют разные переносы строк в один.
- Решение 11 не может корректно работать с текстом Unicode