11种将InputStream转换成String的方法以及性能分析[通俗易懂]

从其他回答中总结出了11种能将InputStream转换成String的方法(如下),并且对所有方法进行了性能测试(对比结果如下):将InputStream转换成String的方法:1.使用IOUtils.toString(ApacheUtils)Stringresult=IOUtils.toString(inputStream,StandardCharse…

大家好,又见面了,我是你们的朋友全栈君。

 

 

从其他回答中总结出了11种能将InputStream转换成String的方法(如下),并且对所有方法进行了性能测试(对比结果如下):

将InputStream转换成String的方法:

1.使用 IOUtils.toString (Apache Utils)

String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);  

2.使用 CharStreams (guava)

String result = CharStreams.toString(new InputStreamReader(
      inputStream, Charsets.UTF_8));

3.使用 Scanner (JDK)

Scanner s = new Scanner(inputStream).useDelimiter("\\A");
String result = s.hasNext() ? s.next() : "";

4.使用 Stream Api (Java 8)

String result = new BufferedReader(new InputStreamReader(inputStream))
  .lines().collect(Collectors.joining("\n"));

5.使用 parallel Stream Api (Java 8)

String result = new BufferedReader(new InputStreamReader(inputStream)).lines()
   .parallel().collect(Collectors.joining("\n"));

6.使用 InputStreamReader 和 StringBuilder (JDK)

final int bufferSize = 1024;
final char[] buffer = new char[bufferSize];
final StringBuilder out = new StringBuilder();
Reader in = new InputStreamReader(inputStream, "UTF-8");
for (; ; ) {
    int rsz = in.read(buffer, 0, buffer.length);
    if (rsz < 0)
        break;
    out.append(buffer, 0, rsz);
}
return out.toString();

7.使用 StringWriter 和 IOUtils.copy (Apache Commons)

StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, "UTF-8");
return writer.toString();

8.使用 ByteArrayOutputStream 和 inputStream.read (JDK)

ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
    result.write(buffer, 0, length);
}
return result.toString("UTF-8");

9.使用 BufferedReader (JDK)

String newLine = System.getProperty("line.separator");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder result = new StringBuilder();
String line; boolean flag = false;
while ((line = reader.readLine()) != null) {
    result.append(flag? newLine: "").append(line);
    flag = true;
}
return result.toString();

10.使用 BufferedInputStream 和 ByteArrayOutputStream (JDK)

BufferedInputStream bis = new BufferedInputStream(inputStream);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result = bis.read();
while(result != -1) {
    buf.write((byte) result);
    result = bis.read();
}
return buf.toString();

11.使用 inputStream.read() 和 StringBuilder (JDK)

注意:
1.方法4、5和9会将不同的换行符(例如:\r\n)全转换成\n。
2.方法11在Unicode编码下不能正确地运行。

性能测试

1.针对较短String的性能测试(长度为175)如下所示,代码贴在了github上(模式是测试平均时间,系统是Linux,其中最好的分数是1,343 )

              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

2.针对较长String的性能测试(长度为50100)如下所示,代码贴在了github上(模式是测试平均时间,系统是Linux,其中最好的分数是200,715 )

              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

3.性能测试图(下图主要描述了在Windows7系统下,随着Input Stream长度变化各个方法平均时间的变化)

11种将InputStream转换成String的方法以及性能分析[通俗易懂]

4.性能测试数据(同样是在Windows7系统下,随着Input Stream长度变化各个方法平均时间的变化)

 length  182    546     1092    3276    9828    29484   58968

 test8  0.38    0.938   1.868   4.448   13.412  36.459  72.708
 test4  2.362   3.609   5.573   12.769  40.74   81.415  159.864
 test5  3.881   5.075   6.904   14.123  50.258  129.937 166.162
 test9  2.237   3.493   5.422   11.977  45.98   89.336  177.39
 test6  1.261   2.12    4.38    10.698  31.821  86.106  186.636
 test7  1.601   2.391   3.646   8.367   38.196  110.221 211.016
 test1  1.529   2.381   3.527   8.411   40.551  105.16  212.573
 test3  3.035   3.934   8.606   20.858  61.571  118.744 235.428
 test2  3.136   6.238   10.508  33.48   43.532  118.044 239.481
 test10 1.593   4.736   7.527   20.557  59.856  162.907 323.147
 test11 3.913   11.506  23.26   68.644  207.591 600.444 1211.545

#####################################

另外

在Java中InputStream和String之间的转化十分普遍,本文主要是总结一下转换的各种方法,包括JDK原生提供的,还有一些外部依赖提供的。

1、InputStream转化为String
1.1 JDK原生提供
方法一:
byte[] bytes = new byte[0];
bytes = new byte[inputStream.available()];
inputStream.read(bytes);
String str = new String(bytes);

方法二:
String result = new BufferedReader(new InputStreamReader(inputStream))
        .lines().collect(Collectors.joining(System.lineSeparator()));

方法三:
String result = new BufferedReader(new InputStreamReader(inputStream))
       .lines().parallel().collect(Collectors.joining(System.lineSeparator()));

方法四:
Scanner s = new Scanner(inputStream).useDelimiter(“\\A”);
String str = s.hasNext() ? s.next() : “”;

方法五:
String resource = new Scanner(inputStream).useDelimiter(“\\Z”).next();
return resource;

方法六:
StringBuilder sb = new StringBuilder();
String line;

BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
while ((line = br.readLine()) != null) {

    sb.append(line);
}
String str = sb.toString();
return str;

方法七:
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {

    result.write(buffer, 0, length);
}
String str = result.toString(StandardCharsets.UTF_8.name());
return str;

方法八:
BufferedInputStream bis = new BufferedInputStream(inputStream);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result = bis.read();
while(result != -1) {

    buf.write((byte) result);
    result = bis.read();
}
String str = buf.toString();
return str;

1.2 Apache Common提供
方法九:
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, StandardCharsets.UTF_8.name());
String str = writer.toString();

方法十:
String str = IOUtils.toString(inputStream, “utf-8”);

1.3 Google Guava提供
方法十一:
String str = CharStreams.toString(new InputStreamReader(inputStream, StandardCharsets.UTF_8));

方法十二:
String str = new String(ByteStreams.toByteArray(inputStream));

针对一个2MB的文件的输入流,多次执行测试如下(单位是毫秒):

方法十: 111
方法十一: 236
方法十二: 36
方法一: 36
方法二: 87
方法三: 66
方法四: 101
方法五: 178
方法六: 40
方法七: 21
方法八: 107
方法九: 31

从上述结果来看,方法七和方法九更好一些,而方法五和方法十一会更差一些。

2、String转化为InputStream
2.1 JDK原生提供
InputStream is = new ByteArrayInputStream(str.getBytes());

2.2 Apache Common提供
InputStream targetStream = IOUtils.toInputStream(str, StandardCharsets.UTF_8.name());

2.3 Google Guava提供
InputStream targetStream =
        new ReaderInputStream(CharSource.wrap(str).openStream(), StandardCharsets.UTF_8.name());

转自:

https://blog.csdn.net/WeakFantasy/article/details/52691041

https://blog.csdn.net/lmy86263/article/details/60479350

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/127769.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【openbmc添加fru信息通过ipmitool命令读取】【后续】

    【openbmc添加fru信息通过ipmitool命令读取】【后续】openbmc 的 fru 配置文章目录一 service1 1 路径 1 2 文件内容 1 3of name to eeprom sh1 4 基于 service 的配置参数文件二 fru 数据模板 yaml 文件 2 1 路径 2 2 内容 2 3yaml 文件数据解析三 配置 3 1yaml 文件加载一 service 将 eeprom 数据读取到 bus 上的 service1 1 路径 xxx project meta phosphor recipes phosphor ipmi phosphor ipmi fru ob

    2025年11月4日
    1
  • mysql er图 属性 联系_数据库er图 联系属性

    mysql er图 属性 联系_数据库er图 联系属性{“moduleinfo”:{“card_count”:[{“count_phone”:1,”count”:1}],”search_count”:[{“count_phone”:4,”count”:4}]},”card”:[{“des”:”阿里云数据库专家保驾护航,为用户的数据库应用系统进行性能和风险评估,参与配合进行数据压测演练,提供数据库优化方面专业建议,在业务高峰期与用户共同保障数据库系统平…

    2022年6月21日
    34
  • scsa笔记1

    scsa笔记1常见的网络安全术语0day通常是指还没有补丁的漏洞。也就是说官方还没有发现或者是发现了还没有开发出安全补丁的漏洞exploit简称exp,漏洞利用APT攻击高级持续性威胁。利用先进的攻击手段对特定目标进行长期持续性网络攻击的攻击形式1.1信息安全脆弱性及常见安全攻击网络环境的开放性在这里插入图片描述协议栈的脆弱性及常见攻击截获嗅探(sniffing)监听(eavesdropping)篡改数据包篡改(tampering)中断拒绝服务(dosing)伪造欺骗(spoof

    2022年6月20日
    39
  • Centos7根分区lvm扩容

    Centos7根分区lvm扩容给根分区/dev/mapper/cl-root扩容20G空间1、先创建一个分区,并把其调整为8eLVM存储卷格式#重读分区表或重启服务器[root@rsq-8-163~]#partprobe#格式化新分区之前先查看根分区是什么文件系统[root@rsq-8-163~]#mount|grep/dev/mapper/cl-root/dev/mapper/cl-r…

    2022年6月20日
    33
  • SQL SERVER的QUOTENAME函数

    SQL SERVER的QUOTENAME函数quotename使函数中的输入成为一个有效的标识符selectQUOTENAME(‘dddd’) 返回[dddd]selectQUOTENAME(‘dddd’,'”‘)返回”dddd”首先,sqlserver里的标识符有一定的规则,比如 你 createtableabc123(…) 那么中间含有空格,它不是符合规则的。 

    2022年7月25日
    16
  • centos7 安装gitea使用

    centos7 安装gitea使用参考官网 https gitea iohttps docs gitea iohttps docs gitea io en us install from binary 关于 GiteaGitea 是一个自己托管的 Git 服务程序 他和 GitHub BitbucketorG 等比较类似 他是从 Gogs 发展而来 不过我们已经 Fork 并且命名为 Gitea 对

    2025年9月25日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号