Java中将InputStream读取为String, 各种方法的性能对比

Summarize other answers I found 11 main ways to do this (see below). And I wrote some performance tests (see results below):

Ways to convert an InputStream to a String:

Using IOUtils.toString (Apache Utils)
String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
Using CharStreams (guava)
String result = CharStreams.toString(new InputStreamReader(
      inputStream, Charsets.UTF_8));
Using Scanner (JDK)
Scanner s = new Scanner(inputStream).useDelimiter("\\A");
String result = s.hasNext() ? s.next() : "";
Using Stream Api (Java 8). Warning: This solution convert different line breaks (like \r\n) to \n.
String result = new BufferedReader(new InputStreamReader(inputStream))
  .lines().collect(Collectors.joining("\n"));
Using parallel Stream Api (Java 8). Warning: This solution convert different line breaks (like \r\n) to \n.
String result = new BufferedReader(new InputStreamReader(inputStream)).lines()
   .parallel().collect(Collectors.joining("\n"));
Using InputStreamReader and 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();
Using StringWriter and IOUtils.copy (Apache Commons)
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, "UTF-8");
return writer.toString();
Using ByteArrayOutputStream and 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");
Using BufferedReader (JDK). Warning: This solution convert different line breaks (like \n\r) to line.separator system property (for example, in Windows to "\r\n").
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();
Using BufferedInputStream and 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();
Using inputStream.read() and StringBuilder (JDK). Warning: This solution has problem with Unicode, for example with Russian text (work correctly only with non-Unicode text)
int ch;
StringBuilder sb = new StringBuilder();
while((ch = inputStream.read()) != -1)
    sb.append((char)ch);
reset();
return sb.toString();
Warning:

Solutions 4, 5 and 9 convert different line breaks to one.
Solution 11 can‘t work correctly with Unicode text
Performance tests

Performance tests for small String (length = 175), url in github (mode = Average Time, system = Linux, score 1,343 is the best):

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
Performance tests for big String (length = 50100), url in github (mode = Average Time, system = Linux, score 200,715 is the best):

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

时间: 02-04

Java中将InputStream读取为String, 各种方法的性能对比的相关文章

使用httpclient实现http链接池与使用HttpURLConnection发送http请求的方法与性能对比

使用httpclient实现http链接池与使用HttpURLConnection发送http请求的方法与性能对比 在项目中需要使用http调用接口,实现了两套发送http请求的方法,一个是使用apache的httpclient提供的http链接池来发送http请求,另一个是使用java原生的HttpURLConnection来发送http请求,并对两者性能进行了对比. 使用httpclient中的链接池发送http请求 使用最新的4.5.2版httpclient进行实现.在maven中引入 <

Java 把 InputStream 转换成 String 的几种方法

我们在 Java 中经常会碰到如何把 InputStream 转换成 String 的情形,比如从文件或网络得到一个 InputStream,需要转换成字符串输出或赋给别的变量. 未真正关注这个问题之前我常用的办法就是按字节一次次读到缓冲区,或是建立 BufferedReader 逐行读取.其实大可不必费此周折,我们可以用 Apache commons IOUtils,或者是 JDK 1.5 后的 Scanner,还可用 Google  Guava 库的 CharStreams.到了 JDK7,

Java中InputStream输入流转String字符串的操作

一.InputStream类中read方法 package com.zhiyin.test; import java.io.InputStream; public class MyTest { public static void main(String[] args) { MyTest myTest = new MyTest(); myTest.test(); } public void test() { try { // 读取测试文件 MyTest test = new MyTest();

[JAVA开发]Properties读取中文乱码解决方法

1 确认工程的统一编码. 例如UTF-8 , project->properties->text file encoding 选择  UTF-8 2 JSP统一编码. 打开JSP文件: 以下都是要关注的地方. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> response.setCharacter

java String、String.concat和StringBuilder性能对比

看到网上有人已经做过对比,并且贴出了代码,然后我运行了之后发现跟我分析的结论差距很大.发现他的代码有个问题,UUID.randomUUID() 首次调用耗时会很高,这个耗时被计算给了String,这对String是不公平的. 原始代码参见:http://www.codes51.com/article/detail_99554.html 修改后的测试代码如下: import java.util.Date; import java.util.UUID; public class StringTest

MySQL查询随机数据的4种方法和性能对比

从MySQL随机选取数据也是我们最常用的一种发发,其最简单的办法就是使用”ORDER BY RAND()”,本文介绍了包括ORDER BY RAND()的4种获取随机数据的方法,并分析了各自的优缺点. 下面从以下四种方案分析各自的优缺点.方案一: 复制代码 代码如下: SELECT * FROM `table` ORDER BY RAND() LIMIT 0,1; 这种方法的问题就是非常慢.原因是因为MySQL会创建一张零时表来保存所有的结果集,然后给每个结果一个随机索引,然后再排序并返回.有几

PHP生成随机密码的4种方法及性能对比

方法一: 1.在 33 – 126 中生成一个随机整数,如 35, 2.将 35 转换成对应的ASCII码字符,如 35 对应 # 3.重复以上 1.2 步骤 n 次,连接成 n 位的密码 该算法主要用到了两个函数,mt_rand ( int $min , int $max )函数用于生成随机整数,其中 $min – $max 为 ASCII 码的范围,这里取 33 -126 ,可以根据需要调整范围,如ASCII码表中 97 – 122 位对应 a – z 的英文字母,具体可参考 ASCII码表

java多线程批量读取文件(七)

新公司入职一个多月了,至今没有事情可以做,十来个新同事都一样抓狂,所以大家都自己学习一些新东西,我最近在看zookeeper,感觉蛮不错的,和微服务的zuul以及eureka功能类似,只是代码复杂了一些.而今天,我所要说的是java多线程读取文件的两个例子: 例子1:java多线程批量读取文件 package face.thread.ReadFile; /** * 多线程读.写文件 *  */import java.io.BufferedReader;import java.io.Buffere

Effective java经验之谈,枚举,注解,方法,通用设计,异常

这几章看的比较快,内容就如同标题一样比较容易理解,所以只有部分内容会在[]中解释,其他的就直接理解标题,并不影响阅读质量. 不过如果时间充足的话,还是仔细读一读原书的内容,相信还是有所收获的.主要最近自己想进入算法与机器学习部分,尽快结束这本书. 另一方面,讨论一些自己感兴趣的内容,我会将搞过的东西总结下.后面可能写一部分关于java字节码阅读以及编写的东西.只所以这么来, 是因为字节码编程还是非常用途实际的,这一"java编译语言"使得String与StringBuilder的性能对