如何在 Java 中将 InputStream 转换为字符串?

Posted

技术标签:

【中文标题】如何在 Java 中将 InputStream 转换为字符串?【英文标题】:How do I convert an InputStream to a String in Java? 【发布时间】:2010-12-18 08:08:52 【问题描述】:

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

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

public String convertStreamToString(InputStream is)  
    // ???

【问题讨论】:

In Java how do a read an input stream in to a string?的可能重复 同意。我已投票决定将此作为重复项关闭,并编辑了另一个问题,以包括此处的一些标题关键字和问题文本。 【参考方案1】:

可以在循环中使用BufferedReader将流读入StringBuilder,然后从StringBuilder获取完整内容:

public String convertStreamToString(InputStream is)  
  BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
  StringBuilder sb = new StringBuilder(); 

  String line = null; 

  try  
    while ((line = reader.readLine()) != null)  
    sb.append(line + "\n"); 
     
   catch (IOException e)  
    e.printStackTrace(); 
   finally  
    try  
      is.close(); 
     catch (IOException e)  
      e.printStackTrace(); 
     
  

  return sb.toString(); 
 

完全披露:这是我在 KodeJava.org 上找到的解决方案。我在这里发布它以供 cmets 和批评。

【讨论】:

请记住,您使用的 BufferedReader 构造函数假定来自 InputStream 的字节采用平台默认文本编码,这可能是错误的。您必须知道编码并在 Reader 构造函数中指定它。 通过使用这个构造函数,你告诉 InputStreamReader 使用默认的平台编码,应该避免。您应该指定数据编码的字符集,以便使用其他三个构造函数之一正确解码。 使用 BufferedReader 在换行符处拆分输入也是不必要的,只是手动将换行符添加到 StringBuilder 和几乎一个 WTF 以实际使用 StringBuilder 来防止创建 String 对象,但是然后调用 append(line + "\n") 而不是 append(line).append("\n")。关闭 InputStream 也不是特别聪明。【参考方案2】:

如果你想简单可靠地做到这一点,我建议使用Apache Jakarta Commons IO库IOUtils.toString(java.io.InputStream, java.lang.String)方法。

【讨论】:

这是简短而甜蜜的方式。 唯一的缺点是你需要在这个库中获取外部依赖,这可能并不总是需要的。 您也需要指定编码,否则它将使用平台默认值,这是不可靠的。【参考方案3】:

这是我的版本,

public static String readString(InputStream inputStream) throws IOException 

    ByteArrayOutputStream into = new ByteArrayOutputStream();
    byte[] buf = new byte[4096];
    for (int n; 0 < (n = inputStream.read(buf));) 
        into.write(buf, 0, n);
    
    into.close();
    return new String(into.toByteArray(), "UTF-8"); // Or whatever encoding

【讨论】:

【参考方案4】:
String text = new Scanner(inputStream).useDelimiter("\\A").next();

唯一需要记住的是正则表达式\A,它匹配输入的开头。这有效地告诉Scanner 标记整个流,从开始到(不合逻辑的)下一个开始...... - 来自Oracle Blog

【讨论】:

【参考方案5】:

一个很好的方法是使用Apache commons@987654322@

IOUtils.toString(inputStream, string);

【讨论】:

【参考方案6】:

自从 Java 9 InputStream.readAllBytes() 更短:

String toString(InputStream inputStream) throws IOException 
   return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); // Or whatever encoding

注意: InputStream 在此示例中关闭。

【讨论】:

以上是关于如何在 Java 中将 InputStream 转换为字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中将 InputStream 读取/转换为字符串?

如何在 Java 中将 InputStream 读取/转换为字符串?

如何在 Java 中将 InputStream 读取/转换为字符串?

如何在 Java 中将 InputStream 转换为字符串?

如何在 Java 中将 InputStream 转换为字符串?

如何在 Java ME 中将 StringBuffer 转换为 InputStream?