2.如何在Java中将InputStream读取/转换为String?| Java Debug 笔记

本文正在参加「Java主题月 – Java Debug笔记活动」,详情查看<活动链接>

提问:如何在Java中将InputStream读取/转换为String?

如果有一个java.io.InputStream对象,应该如何处理该对象并产生一个String?


假设我有一个InputStream包含文本数据的文件,并且想将其转换String为,例如,我可以将其写入日志文件。

InputStream将并将其转换为的最简单方法是String什么?

public String convertStreamToString(InputStream is) {
    // ???
}
复制代码

总结多个答案,以及性能测试:

  1. 使用IOUtils.toString(Apache Utils)
 String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
复制代码
  1. 使用CharStreams(Guava)
 String result = CharStreams.toString(new InputStreamReader(
       inputStream, Charsets.UTF_8));
复制代码
  1. Using Scanner (JDK)
 Scanner s = new Scanner(inputStream).useDelimiter("\\A");
 String result = s.hasNext() ? s.next() : "";
复制代码
  1. 使用streamAPI(Java 8)。警告:此解决方案会将不同的换行符(如\r\n)转换为\n。
 String result = new BufferedReader(new InputStreamReader(inputStream))
   .lines().collect(Collectors.joining("\n"));
复制代码
  1. 使用 parallel Stream API(Java 8)。警告:此解决方案会将不同的换行符(如\r\n)转换为\n
 String result = new BufferedReader(new InputStreamReader(inputStream))
    .lines().parallel().collect(Collectors.joining("\n"));
复制代码
  1. 使用InputStreamReader和StringBuilder(JDK)
 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();
复制代码
  1. 使用StringWriter和IOUtils.copy(Apache Commons)
StringWriter writer = new StringWriter();
 IOUtils.copy(inputStream, writer, "UTF-8");
 return writer.toString();
复制代码
  1. 使用ByteArrayOutputStream和inputStream.read(JDK)
 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");
复制代码
  1. 使用BufferedReader(JDK)。警告:此解决方案将不同的换行符(如\n\r)转换为line.separator系统属性(例如,在Windows中转换为“ \ r \ n”)。
 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();
复制代码
  1. 使用BufferedInputStream和ByteArrayOutputStream(JDK)
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");
复制代码
  1. 使用inputStream.read()和StringBuilder(JDK)。警告:此解决方案存在Unicode问题,例如俄语文本(仅适用于非Unicode文本)
StringBuilder sb = new StringBuilder();
for (int ch; (ch = inputStream.read()) != -1; ) {
    sb.append((char) ch);
}
return sb.toString();
复制代码

警告:

解决方案4、5和9将不同的换行符转换为1。

解决方案11不能正确处理Unicode文本

性能测试:

针对小型String(长度= 175)的性能测试(模式=平均时间,系统= Linux,最高分= 1343):

              Benchmark                         Mode  Cnt   Score   Error  Units
 8. ByteArrayOutputStream and read (JDK)        avgt   10   1,343 ± 0,028  us/op
 6. InputStreamReader and StringBuilder (JDK)   avgt   10   6,980 ± 0,404  us/op
10. BufferedInputStream, ByteArrayOutputStream  avgt   10   7,437 ± 0,735  us/op
11. InputStream.read() and StringBuilder (JDK)  avgt   10   8,977 ± 0,328  us/op
 7. StringWriter and IOUtils.copy (Apache)      avgt   10  10,613 ± 0,599  us/op
 1. IOUtils.toString (Apache Utils)             avgt   10  10,605 ± 0,527  us/op
 3. Scanner (JDK)                               avgt   10  12,083 ± 0,293  us/op
 2. CharStreams (guava)                         avgt   10  12,999 ± 0,514  us/op
 4. Stream Api (Java 8)                         avgt   10  15,811 ± 0,605  us/op
 9. BufferedReader (JDK)                        avgt   10  16,038 ± 0,711  us/op
 5. parallel Stream Api (Java 8)                avgt   10  21,544 ± 0,583  us/op
复制代码

针对大型String(长度= 50100)的性能测试(模式=平均时间,系统= Linux,最高分 = 200715)

               Benchmark                        Mode  Cnt   Score        Error  Units
 8. ByteArrayOutputStream and read (JDK)        avgt   10   200,715 ±   18,103  us/op
 1. IOUtils.toString (Apache Utils)             avgt   10   300,019 ±    8,751  us/op
 6. InputStreamReader and StringBuilder (JDK)   avgt   10   347,616 ±  130,348  us/op
 7. StringWriter and IOUtils.copy (Apache)      avgt   10   352,791 ±  105,337  us/op
 2. CharStreams (guava)                         avgt   10   420,137 ±   59,877  us/op
 9. BufferedReader (JDK)                        avgt   10   632,028 ±   17,002  us/op
 5. parallel Stream Api (Java 8)                avgt   10   662,999 ±   46,199  us/op
 4. Stream Api (Java 8)                         avgt   10   701,269 ±   82,296  us/op
10. BufferedInputStream, ByteArrayOutputStream  avgt   10   740,837 ±    5,613  us/op
 3. Scanner (JDK)                               avgt   10   751,417 ±   62,026  us/op
11. InputStream.read() and StringBuilder (JDK)  avgt   10  2919,350 ± 1101,942  us/op
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享