如果您有java.io.InputStream对象,应该如何处理该对象并生成String?


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

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

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

当前回答

考虑到文件,首先应该获得java.io.Reader实例。然后可以将其读取并添加到StringBuilder中(如果我们不在多个线程中访问StringBuffer,我们就不需要StringBuffer了,StringBuilder速度更快)。这里的技巧是我们在块中工作,因此不需要其他缓冲流。块大小被参数化以用于运行时性能优化。

public static String slurp(final InputStream is, final int bufferSize) {
    final char[] buffer = new char[bufferSize];
    final StringBuilder out = new StringBuilder();
    try (Reader in = new InputStreamReader(is, "UTF-8")) {
        for (;;) {
            int rsz = in.read(buffer, 0, buffer.length);
            if (rsz < 0)
                break;
            out.append(buffer, 0, rsz);
        }
    }
    catch (UnsupportedEncodingException ex) {
        /* ... */
    }
    catch (IOException ex) {
        /* ... */
    }
    return out.toString();
}

其他回答

就reduce和concat而言,它可以在Java 8中表示为:

String fromFile = new BufferedReader(new   
InputStreamReader(inputStream)).lines().reduce(String::concat).get();

另一个,对于所有Spring用户:

import java.nio.charset.StandardCharsets;
import org.springframework.util.FileCopyUtils;

public String convertStreamToString(InputStream is) throws IOException { 
    return new String(FileCopyUtils.copyToByteArray(is), StandardCharsets.UTF_8);
}

org.springframework.util.StreamUtils中的实用程序方法与FileCopyUtils中类似,但它们在完成后会使流保持打开状态。

为了完整起见,这里是Java 9解决方案:

public static String toString(InputStream input) throws IOException {
    return new String(input.readAllBytes(), StandardCharsets.UTF_8);
}

这使用添加到Java9中的readAllBytes方法。

这里有一种仅使用标准Java库的方法(请注意,流没有关闭,您的里程可能会有所不同)。

static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}

我从“愚蠢的扫描仪技巧”一文中学会了这个技巧。它工作的原因是因为Scanner迭代流中的令牌,在这种情况下,我们使用“输入边界的开始”(\A)来分离令牌,从而为流的整个内容只提供一个令牌。

注意,如果您需要明确输入流的编码,可以向Scanner构造函数提供第二个参数,指示要使用的字符集(例如“UTF-8”)。

雅各布也收到了帽子提示,他曾向我指出了上述文章。

如果需要将字符串转换为没有外部库的特定字符集,则:

public String convertStreamToString(InputStream is) throws IOException {
  try (ByteArrayOutputStream baos = new ByteArrayOutputStream();) {
    is.transferTo(baos);
    return baos.toString(StandardCharsets.UTF_8);
  }
}