java中有效的输入流到字符串方法

Posted

技术标签:

【中文标题】java中有效的输入流到字符串方法【英文标题】:efficient input stream to string method in java 【发布时间】:2010-11-26 21:11:56 【问题描述】:

因此,我在我的(诚然非常简单的)Java 应用程序上运行分析器,我惊讶地发现,在时间上仅次于需要发出 HTTP 请求的方法是我的 inputStreamToString 方法。目前是这样定义的:

public static String inputStreamToString(InputStream in) throws IOException 
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    StringBuilder sb = new StringBuilder();
    String line = null;
    while ((line = reader.readLine()) != null) 
        sb.append(line).append("\n");
    
    in.close();
    return sb.toString();

我怎样才能加快速度? (是的,我确实需要字符串,不,InputStrings 不是那么大,不,这个方法的调用频率低于程序中的大多数方法,不,我没有办法避免需要转化率。)

【问题讨论】:

嗯,这就是所有 I/O 发生的地方(我假设分析器包括 readLine() 等待数据进来的所有时间)。您可以做的唯一明显的事情是使用足够大的缓冲区预初始化 StringBuilder,这样它就不必重新分配内存,但我认为所有内容都比读取数据所需的时间小。 @EboMike 已经把它钉在那里了。除此之外,我唯一能想到的另一件事是跳过BufferedReader 并提供你自己的缓冲区来读入——这也可以节省readLine 调用,因为你真的不在乎读一行一次。 我想我不妨把它变成一个答案:) 除非您想转换换行符或解析行,否则逐行阅读没有多大意义。我宁愿通过固定大小的缓冲区逐个字符地读取:gist.github.com/fkirc/a231c817d582e114e791b77bb33e30e9 【参考方案1】:

嗯,这就是所有 I/O 发生的地方(我假设分析器包括 readLine() 等待数据进来的所有时间)。您可以做的唯一明显的事情是使用足够大的缓冲区预初始化 StringBuilder,这样它就不必重新分配内存,但我认为所有内容都比读取数据所需的时间小了。

除此之外 - 您受 I/O 限制。通过网络接收数据只是需要时间。

编辑:也可以包括 casablanca 的评论:与其逐行读取然后添加换行符,不如使用一个简单的读取器,它具有您提供的相当大的缓冲区,并且只是块读取所有内容。无需逐行阅读,因为您似乎只是复制了整个输入数据。手动逐行执行的唯一原因是,如果您想将换行符(如 \r\n)标准化为标准的 \n

【讨论】:

【参考方案2】:

尝试使用来自 jakarta commons 的 IOUtils.copy()。 创建 ByteArrayOutputStream,将 HTTPRequest 流中的字节复制到此 ByteArray,然后使用 new String(bytes, "UTF-8") 创建字符串。

我相信它可以更快...

但是您的代码看起来完全是为了说明良好的风格和良好的编码而编写的。我真的不明白这里有什么可能如此无效。可能这需要时间,因为您的其余逻辑相对简单并且写得很好?我的意思是,虽然这段代码花费了相对较长的时间,但这不是太关键吗?

【讨论】:

以上是关于java中有效的输入流到字符串方法的主要内容,如果未能解决你的问题,请参考以下文章

java中nextLine()和next()的区别

Java流程控制01:用户交互Scanner

Java之字符串输入next()与nextLine()

Java中next() 与 nextLine() 区别

JAVA基础复习-转换流的使用

Java sanner类中next和nextLine的区别